-
Notifications
You must be signed in to change notification settings - Fork 91
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
595 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -214,3 +214,4 @@ dist/ | |
packages/*/dist/ | ||
test/e2e/log/ | ||
test/e2e/screenshots/diff/ | ||
storybook/build/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
## How to use | ||
### Component | ||
```js | ||
import { VanillaRenderer, Renderer } from "@egjs/infinitegrid"; | ||
|
||
// Use VanillaRenderer or Renderer | ||
|
||
// Component | ||
class Component { | ||
constructor(renderer: Renderer) { | ||
this.renderer = renderer; | ||
} | ||
// Sync items and elements | ||
render(items) { | ||
this.renderer.render(items); | ||
} | ||
|
||
// Force update if you want to show only part of it internally | ||
update() { | ||
// If true is returned, the update event is not called. (for vanilla) | ||
// If false is returned, the update event is called. (for framework) | ||
if (this.renderer.update()) { | ||
// vanilla | ||
this.render(); | ||
} | ||
} | ||
|
||
// set renderer container for vanilla | ||
setContainer(container) { | ||
this.renderer.setContainer(container); | ||
} | ||
} | ||
|
||
``` | ||
### Vanilla | ||
```js | ||
const component = new Component(new VanillaRenderer()); | ||
|
||
// render item with element | ||
component.render([ | ||
{ key: 1, element: element1 }, | ||
{ key: 2, element: element2 }, | ||
{ key: 3, element: element3 }, | ||
]); | ||
|
||
|
||
component.update(); | ||
``` | ||
|
||
### Framework | ||
```jsx | ||
import * as React from "react"; | ||
import { Renderer } from "@egjs/infinitegrid"; | ||
|
||
class ReactComponent extends React.Component { | ||
containerRef = React.createRef(); | ||
render() { | ||
const items = [ | ||
{ key: 1 }, | ||
{ key: 2 }, | ||
{ key: 3 }, | ||
]; | ||
// render only items | ||
this.component?.render(items); | ||
return <div ref={this.containerRef} onClick={() => { | ||
this.component.update(); | ||
}}> | ||
{items.map((item) => (<div key={item.key}>{item.key}</div>))} | ||
</div>; | ||
} | ||
componentDidUpdate() { | ||
// update elements in items | ||
this.renderer.updated(this.containerRef.current!.children); | ||
} | ||
componentDidMount() { | ||
const renderer = new Renderer(); | ||
const component = new Component(renderer); | ||
|
||
this.renderer = renderer; | ||
this.component = component; | ||
|
||
component.render([ | ||
{ key: 1 }, | ||
{ key: 2 }, | ||
{ key: 3 }, | ||
]); | ||
renderer.updated(this.containerRef.current!.children); | ||
renderer.on("update", () => { | ||
this.forceUpdate(); | ||
}); | ||
} | ||
} | ||
``` | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import Component from "@egjs/component"; | ||
import { diff, DiffResult } from "@egjs/list-differ"; | ||
|
||
export interface RendererItem { | ||
key: string | number; | ||
element?: Element | null; | ||
} | ||
|
||
export interface OnRendererUpdated<T extends RendererItem = RendererItem> { | ||
items: T[]; | ||
elements: Element[]; | ||
isChanged: boolean; | ||
diffResult: DiffResult<T>; | ||
} | ||
|
||
export interface RendererEvents<T extends RendererItem = RendererItem> { | ||
update: void; | ||
updated: OnRendererUpdated<T>; | ||
} | ||
|
||
export class Renderer<T extends RendererItem = RendererItem> extends Component<RendererEvents> { | ||
protected items: T[] = []; | ||
protected container: Element | null = null; | ||
private _diffResult: DiffResult<T>; | ||
|
||
public getItems() { | ||
return this.items; | ||
} | ||
public setContainer(container: Element) { | ||
this.container = container; | ||
} | ||
public setItems(items: T[]) { | ||
this.items = items; | ||
} | ||
public render(nextItems: T[]) { | ||
return this.syncItems(nextItems); | ||
} | ||
public update() { | ||
this.trigger("update"); | ||
return false; | ||
} | ||
public updated(nextElements: ArrayLike<Element>) { | ||
const items = this.items; | ||
const diffResult = this._diffResult; | ||
const isChanged = !!(diffResult.added.length || diffResult.removed.length || diffResult.changed.length); | ||
|
||
items.forEach((item, i) => { | ||
item.element = nextElements[i]; | ||
}); | ||
|
||
this.trigger("updated", { | ||
items, | ||
elements: [].slice.call(nextElements), | ||
diffResult: this._diffResult, | ||
isChanged, | ||
}); | ||
|
||
return isChanged; | ||
} | ||
protected syncItems(nextItems: T[]) { | ||
const result = diff(this.items, nextItems, (item) => item.key); | ||
|
||
this._diffResult = result; | ||
this.items = nextItems; | ||
|
||
return result; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { GridItem } from "@egjs/grid"; | ||
import { RendererItem } from "./Renderer"; | ||
import { VanillaRenderer } from "./VanillaRenderer"; | ||
|
||
export interface GridRendererItem extends RendererItem { | ||
orgItem: GridItem; | ||
} | ||
|
||
export class VanillaGridRenderer extends VanillaRenderer<GridRendererItem> { | ||
constructor() { | ||
super(); | ||
} | ||
public syncItems(nextItems: GridRendererItem[]) { | ||
const result = super.syncItems(nextItems); | ||
const { | ||
added, | ||
list, | ||
} = result; | ||
added.forEach((index) => { | ||
const orgItem = nextItems[index].orgItem; | ||
|
||
// createElement(orgItem.element); | ||
|
||
list[index].element = orgItem.element!; | ||
}); | ||
|
||
return result; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { Renderer, RendererItem } from "./Renderer"; | ||
|
||
export class VanillaRenderer<T extends RendererItem = RendererItem> extends Renderer<T> { | ||
public render(nextItems: T[]) { | ||
const container = this.container!; | ||
const result = this.syncItems(nextItems); | ||
const { | ||
prevList, | ||
removed, | ||
ordered, | ||
added, | ||
} = result; | ||
const diffList = [...prevList]; | ||
|
||
removed.forEach((index) => { | ||
diffList.splice(index, 1); | ||
container.removeChild(prevList[index].element!); | ||
}); | ||
ordered.forEach(([prevIndex, nextIndex]) => { | ||
const item = diffList.splice(prevIndex, 1)[0]; | ||
|
||
diffList.splice(nextIndex, 0, item); | ||
container.insertBefore(item.element!, diffList[nextIndex + 1]?.element ?? null); | ||
}); | ||
added.forEach((index) => { | ||
const item = nextItems[index]; | ||
|
||
diffList.splice(index, 0, item); | ||
container.insertBefore(item.element!, diffList[index + 1]?.element ?? null); | ||
}); | ||
|
||
this.updated(container.children); | ||
return result; | ||
} | ||
public update() { | ||
return true; | ||
} | ||
} |
Oops, something went wrong.