├── .gitignore
├── .npmignore
├── README.md
├── lib
└── index.js
└── package.json
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled source #
2 | ###################
3 | *.com
4 | *.class
5 | *.dll
6 | *.exe
7 | *.o
8 | *.so
9 |
10 | # Packages #
11 | ############
12 | # it's better to unpack these files and commit the raw source
13 | # git has its own built in compression methods
14 | *.7z
15 | *.dmg
16 | *.gz
17 | *.iso
18 | *.jar
19 | *.rar
20 | *.tar
21 | *.zip
22 |
23 | # Logs and databases #
24 | ######################
25 | *.log
26 | *.sql
27 | *.sqlite
28 |
29 | # OS generated files #
30 | ######################
31 | .DS_Store
32 | .DS_Store?
33 | ._*
34 | .Spotlight-V100
35 | .Trashes
36 | ehthumbs.db
37 | Thumbs.db
38 |
39 |
40 | # Custom
41 | #####################
42 | /node_modules
43 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 | /test.js
3 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | React Packery Mixin
2 | ===================
3 |
4 | #### Introduction:
5 | A mixin for React.js to use Metafizzy Packery (Also available as a [component](https://github.com/eiriklv/react-packery-component) - you should use that instead!)
6 |
7 | #### Which version should I use?
8 | React Packery Mixin 0.2.x is compatible with React 0.14 and above only. For older versions of React, use a 0.1.x version of React Packery Mixin.
9 |
10 | #### Usage:
11 |
12 | * The mixin is bundled with packery, so no additional dependencies needed!
13 | * You can optionally include Packery as a script tag as an override
14 | ``
15 |
16 | * To use the mixin
17 | * require the mixin
18 | * pass a reference and a packery options object
19 | * make sure you use the same reference as `ref` in your component
20 | * if you need to - access the packery object through `this.packery` in your component
21 |
22 | * example use in code
23 |
24 | ```js
25 | /** @jsx React.DOM */
26 |
27 | 'use strict';
28 |
29 | var React = require('react');
30 |
31 | var PackeryMixin = require('react-packery-mixin');
32 |
33 | var packeryOptions = {
34 | transitionDuration: 0
35 | };
36 |
37 | module.exports = React.createClass({
38 | displayName: 'SomeComponent',
39 |
40 | mixins: [PackeryMixin('packeryContainer', packeryOptions)],
41 |
42 | render: function () {
43 | var childElements = this.props.elements.map(function(element){
44 | return (
45 |
46 | {element.name}
47 |
48 | );
49 | });
50 |
51 | return (
52 |
53 | {childElements}
54 |
55 | );
56 | }
57 | });
58 | ```
59 |
60 | # License information (Metafizzy)
61 |
62 | ## Commercial license
63 |
64 | Packery may be used in commercial projects and applications with the one-time purchase of a commercial license. If you are paid to do your job, and part of your job is implementing Packery, a commercial license is required.
65 |
66 | http://packery.metafizzy.co/license.html
67 |
68 | For non-commercial, personal, or open source projects and applications, you may use Packery under the terms of the [GPL v3 License](http://choosealicense.com/licenses/gpl-v3/). You may use Packery for free.
69 |
70 | ---
71 |
72 | Copyright (c) 2014 Metafizzy
73 |
--------------------------------------------------------------------------------
/lib/index.js:
--------------------------------------------------------------------------------
1 | var isBrowser = (typeof window !== 'undefined');
2 | var Packery = isBrowser ? window.Packery || require('packery') : null;
3 | var imagesloaded = isBrowser ? require('imagesloaded') : null;
4 |
5 | function PackeryMixin() {
6 | return function(reference, options) {
7 | return {
8 | packery: false,
9 |
10 | domChildren: [],
11 |
12 | initializePackery: function(force) {
13 | if (!this.packery || force) {
14 | this.packery = new Packery(this.refs[reference], options);
15 | this.domChildren = this.getNewDomChildren();
16 | }
17 | },
18 |
19 | getNewDomChildren: function () {
20 | var node = this.refs[reference];
21 | var children = options.itemSelector ? node.querySelectorAll(options.itemSelector) : node.children;
22 |
23 | return Array.prototype.slice.call(children);
24 | },
25 |
26 | diffDomChildren: function() {
27 | var oldChildren = this.domChildren;
28 | var newChildren = this.getNewDomChildren();
29 |
30 | var removed = oldChildren.filter(function(oldChild) {
31 | return !~newChildren.indexOf(oldChild);
32 | });
33 |
34 | var added = newChildren.filter(function(newChild) {
35 | return !~oldChildren.indexOf(newChild);
36 | });
37 |
38 | var moved = [];
39 |
40 | if (removed.length === 0) {
41 | moved = oldChildren.filter(function(child, index) {
42 | return index !== newChildren.indexOf(child);
43 | });
44 | }
45 |
46 | this.domChildren = newChildren;
47 |
48 | return {
49 | old: oldChildren,
50 | 'new': newChildren,
51 | removed: removed,
52 | added: added,
53 | moved: moved
54 | };
55 | },
56 |
57 | performLayout: function() {
58 | var diff = this.diffDomChildren();
59 |
60 | if (diff.removed.length > 0) {
61 | this.packery.remove(diff.removed);
62 | this.packery.reloadItems();
63 | }
64 |
65 | if (diff.added.length > 0) {
66 | this.packery.appended(diff.added);
67 | }
68 |
69 | if (diff.moved.length > 0) {
70 | this.packery.reloadItems();
71 | }
72 |
73 | this.packery.layout();
74 | },
75 |
76 | imagesLoaded: function() {
77 | imagesloaded(this.refs[reference], function(instance) {
78 | this.packery.layout();
79 | }.bind(this));
80 | },
81 |
82 | componentDidMount: function() {
83 | if (!isBrowser) return;
84 |
85 | this.initializePackery();
86 | this.performLayout();
87 | this.imagesLoaded();
88 | },
89 |
90 | componentDidUpdate: function() {
91 | if (!isBrowser) return;
92 |
93 | this.performLayout();
94 | this.imagesLoaded();
95 | },
96 |
97 | componentWillReceiveProps: function() {
98 | this._timer = setTimeout(function() {
99 | this.packery.reloadItems();
100 | this.forceUpdate();
101 | }.bind(this), 0);
102 | },
103 |
104 | componentWillUnmount: function() {
105 | clearTimeout(this._timer);
106 | }
107 | }
108 | };
109 | }
110 |
111 | module.exports = PackeryMixin();
112 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-packery-mixin",
3 | "version": "0.2.0",
4 | "main": "./lib/index",
5 | "description": "A packery mixin for React.js",
6 | "dependencies": {
7 | "packery": "eiriklv/packery",
8 | "imagesloaded": "eiriklv/imagesloaded"
9 | },
10 | "devDependencies": {},
11 | "scripts": {
12 | "test": "echo \"Error: no test specified\" && exit 1"
13 | },
14 | "repository": {
15 | "type": "git",
16 | "url": "git://github.com/eiriklv/react-packery-mixin.git"
17 | },
18 | "keywords": [
19 | "react",
20 | "mixin",
21 | "masonry",
22 | "packery",
23 | "isotope",
24 | "react-component"
25 | ],
26 | "author": "Eirik Vullum (http://www.evconsult.no/)",
27 | "bugs": {
28 | "url": "https://github.com/eiriklv/react-packery-mixin/issues"
29 | },
30 | "homepage": "https://github.com/eiriklv/react-packery-mixin"
31 | }
32 |
--------------------------------------------------------------------------------