├── .gitignore ├── .idea ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── misc.xml └── modules.xml ├── 01_non_mobx_example ├── 01_non_mobx_example.iml ├── index.html └── js │ ├── swatch-renderer-viewer.js │ └── swatch-store.js ├── 02_mobx_autorun ├── index.html └── js │ └── swatch-renderer-viewer.js ├── 03_mobx_observer ├── index-non-optimized.html ├── index.html └── js │ └── swatch-renderer-viewer.js ├── 04_mobx_stateless_func ├── index.html └── js │ └── swatch-renderer-viewer.js ├── 05_mobx_perf ├── index.html └── js │ └── swatch-renderer-viewer.js ├── README.md ├── reactSwatchMobxDemo.iml └── shared_assets ├── observable-swatch-store.js ├── style.css ├── swatch-data-1.js └── swatch-data-2.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### JetBrains template 3 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 4 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 5 | 6 | # User-specific stuff: 7 | .idea/workspace.xml 8 | .idea/tasks.xml 9 | .idea/dictionaries 10 | .idea/vcs.xml 11 | .idea/jsLibraryMappings.xml 12 | 13 | # Sensitive or high-churn files: 14 | .idea/dataSources.ids 15 | .idea/dataSources.xml 16 | .idea/dataSources.local.xml 17 | .idea/sqlDataSources.xml 18 | .idea/dynamic.xml 19 | .idea/uiDesigner.xml 20 | 21 | # Gradle: 22 | .idea/gradle.xml 23 | .idea/libraries 24 | 25 | # Mongo Explorer plugin: 26 | .idea/mongoSettings.xml 27 | 28 | ## File-based project format: 29 | *.iws 30 | 31 | ## Plugin-specific files: 32 | 33 | # IntelliJ 34 | /out/ 35 | 36 | # mpeltonen/sbt-idea plugin 37 | .idea_modules/ 38 | 39 | # JIRA plugin 40 | atlassian-ide-plugin.xml 41 | 42 | # Crashlytics plugin (for Android Studio and IntelliJ) 43 | com_crashlytics_export_strings.xml 44 | crashlytics.properties 45 | crashlytics-build.properties 46 | fabric.properties 47 | 48 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 1.8 21 | 22 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /01_non_mobx_example/01_non_mobx_example.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /01_non_mobx_example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 01 Swatch viewer non-mobx 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /01_non_mobx_example/js/swatch-renderer-viewer.js: -------------------------------------------------------------------------------- 1 | /** @namespace Swatch */ 2 | (function () { 3 | "use strict"; 4 | 5 | Swatch.ViewerFullRenderer = React.createClass({ 6 | displayName: 'ViewerFullRenderer', 7 | render: function () { 8 | var store = this.props.store; 9 | var selectedSwatch = store.getSelectedSwatch(); 10 | 11 | return React.DOM.div({ 12 | className: 'swatch-viewer' 13 | }, 14 | React.DOM.h1(null, store.title), 15 | React.createElement(Swatch.selectedSwatchRenderer, {selectedSwatch: selectedSwatch}), 16 | React.createElement(Swatch.swatchGroupRenderer, { 17 | swatches: store.swatches, 18 | setSelectedSwatch: _.bind(store.setSelectedSwatch, store) 19 | }) 20 | ); 21 | 22 | } 23 | }); 24 | 25 | Swatch.selectedSwatchRenderer = React.createClass({ 26 | displayName: 'selectedSwatchRenderer', 27 | render: function () { 28 | var selectedSwatch = this.props.selectedSwatch; 29 | return React.DOM.div({ 30 | className: 'selected-swatch-container' 31 | }, 32 | React.DOM.img({ 33 | height: 260, 34 | width: 260, 35 | alt: selectedSwatch.name, 36 | className: 'selected-swatch-image', 37 | src: selectedSwatch.image + '?wid=260&hei=260' 38 | }), 39 | 40 | React.DOM.strong({ 41 | className: 'selected-swatch-name' 42 | }, selectedSwatch.name) 43 | ); 44 | } 45 | }); 46 | 47 | Swatch.swatchGroupRenderer = React.createClass({ 48 | displayName: 'swatchGroupRenderer', 49 | render: function () { 50 | 51 | var renderedSwatches = this.props.swatches.map(function (swatch) { 52 | return React.createElement(Swatch.swatchThumbnailRenderer, 53 | { 54 | key: swatch.materialId, 55 | swatch: swatch, 56 | setSelectedSwatch: this.props.setSelectedSwatch 57 | }); 58 | }, this); 59 | 60 | return React.DOM.div({ 61 | className: 'swatch-container' 62 | }, 63 | renderedSwatches 64 | ); 65 | } 66 | }); 67 | 68 | Swatch.swatchThumbnailRenderer = React.createClass({ 69 | displayName: 'swatchThumbnailRenderer', 70 | render: function () { 71 | var swatch = this.props.swatch; 72 | 73 | var className = 'swatch' + (swatch.selected ? ' selected' : ''); 74 | 75 | return React.DOM.div({ 76 | className: className, 77 | key: swatch.materialId, 78 | onClick: this.swatchClickHandler 79 | }, 80 | React.DOM.img({ 81 | height: 31, 82 | width: 31, 83 | alt: swatch.name, 84 | src: swatch.image + '?wid=31&hei=31' 85 | }) 86 | ); 87 | }, 88 | swatchClickHandler: function () { 89 | console.log('swatch id: ' + this.props.swatch.materialId); 90 | this.props.setSelectedSwatch(this.props.swatch.materialId); 91 | } 92 | }); 93 | 94 | }()); -------------------------------------------------------------------------------- /01_non_mobx_example/js/swatch-store.js: -------------------------------------------------------------------------------- 1 | /** @namespace Swatch */ 2 | (function () { 3 | "use strict"; 4 | 5 | window.Swatch = {}; 6 | 7 | Swatch.SwatchStore = function (swatchJSONData) { 8 | _.assign(this, swatchJSONData); 9 | 10 | // Actions for others to listen to 11 | this.listenableActions = { 12 | swatchDataChanged: function () { 13 | var sig = new signals.Signal(); 14 | sig.memorize = true; 15 | return sig; 16 | }() 17 | }; 18 | this.listenableActions.swatchDataChanged.dispatch(); 19 | }; 20 | 21 | Swatch.SwatchStore.prototype.getSelectedSwatch = function () { 22 | return _.find(this.swatches, 'selected'); 23 | }; 24 | 25 | Swatch.SwatchStore.prototype.setSelectedSwatch = function (materialId) { 26 | this.getSelectedSwatch().selected = false; 27 | _.find(this.swatches, {materialId: materialId}).selected = true; 28 | this.listenableActions.swatchDataChanged.dispatch(); 29 | }; 30 | 31 | }()); -------------------------------------------------------------------------------- /02_mobx_autorun/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Swatch viewer non-mobx 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /02_mobx_autorun/js/swatch-renderer-viewer.js: -------------------------------------------------------------------------------- 1 | /** @namespace Swatch */ 2 | (function () { 3 | "use strict"; 4 | 5 | Swatch.ViewerFullRenderer = function ViewerFullRenderer (props) { 6 | var store = props.store; 7 | var selectedSwatch = store.selectedSwatch; 8 | 9 | return React.DOM.div({ 10 | className: 'swatch-viewer' 11 | }, 12 | React.DOM.h1(null, store.title), 13 | React.createElement(Swatch.selectedSwatchRenderer, {selectedSwatch: selectedSwatch}), 14 | React.createElement(Swatch.swatchGroupRenderer, { 15 | swatches: store.swatches, 16 | setSelectedSwatch: store.setSelectedSwatch 17 | }) 18 | ); 19 | }; 20 | 21 | Swatch.selectedSwatchRenderer = React.createClass({ 22 | displayName: 'selectedSwatchRenderer', 23 | render: function () { 24 | var selectedSwatch = this.props.selectedSwatch; 25 | return React.DOM.div({ 26 | className: 'selected-swatch-container' 27 | }, 28 | React.DOM.img({ 29 | height: 260, 30 | width: 260, 31 | alt: selectedSwatch.name, 32 | className: 'selected-swatch-image', 33 | src: selectedSwatch.image + '?wid=260&hei=260' 34 | }), 35 | 36 | React.DOM.strong({ 37 | className: 'selected-swatch-name' 38 | }, selectedSwatch.name) 39 | ); 40 | } 41 | }); 42 | 43 | Swatch.swatchGroupRenderer = React.createClass({ 44 | displayName: 'swatchGroupRenderer', 45 | render: function () { 46 | 47 | var renderedSwatches = this.props.swatches.map(function (swatch) { 48 | return React.createElement(Swatch.swatchThumbnailRenderer, 49 | { 50 | key: swatch.materialId, 51 | swatch: swatch, 52 | setSelectedSwatch: this.props.setSelectedSwatch 53 | }); 54 | }, this); 55 | 56 | return React.DOM.div({ 57 | className: 'swatch-container' 58 | }, 59 | renderedSwatches 60 | ); 61 | } 62 | }); 63 | 64 | Swatch.swatchThumbnailRenderer = React.createClass({ 65 | displayName: 'swatchThumbnailRenderer', 66 | render: function () { 67 | var swatch = this.props.swatch; 68 | 69 | var className = 'swatch' + (swatch.selected ? ' selected' : ''); 70 | 71 | return React.DOM.div({ 72 | className: className, 73 | key: swatch.materialId, 74 | onClick: this.swatchClickHandler 75 | }, 76 | React.DOM.img({ 77 | height: 31, 78 | width: 31, 79 | alt: swatch.name, 80 | src: swatch.image + '?wid=31&hei=31' 81 | }) 82 | ); 83 | }, 84 | swatchClickHandler: function () { 85 | console.log('swatch id: ' + this.props.swatch.materialId); 86 | this.props.setSelectedSwatch(this.props.swatch.materialId); 87 | } 88 | }); 89 | 90 | }()); -------------------------------------------------------------------------------- /03_mobx_observer/index-non-optimized.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Swatch viewer non-mobx 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /03_mobx_observer/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 03 Swatch viewer non-mobx 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /03_mobx_observer/js/swatch-renderer-viewer.js: -------------------------------------------------------------------------------- 1 | /** @namespace Swatch */ 2 | (function () { 3 | "use strict"; 4 | 5 | Swatch.ViewerFullRenderer = mobxReact.observer(React.createClass({ 6 | displayName: 'ViewerFullRenderer', 7 | render: function () { 8 | var store = this.props.store; 9 | var selectedSwatch = store.selectedSwatch; 10 | 11 | return React.DOM.div({ 12 | className: 'swatch-viewer' 13 | }, 14 | // React.createElement(mobxDevtools.default), 15 | React.DOM.h1(null, store.title), 16 | React.createElement(Swatch.selectedSwatchRenderer, {selectedSwatch: selectedSwatch}), 17 | React.createElement(Swatch.swatchGroupRenderer, { 18 | swatches: store.swatches, 19 | setSelectedSwatch: store.setSelectedSwatch 20 | }) 21 | ); 22 | 23 | } 24 | })); 25 | 26 | Swatch.selectedSwatchRenderer = mobxReact.observer(React.createClass({ 27 | displayName: 'selectedSwatchRenderer', 28 | render: function () { 29 | var selectedSwatch = this.props.selectedSwatch; 30 | return React.DOM.div({ 31 | className: 'selected-swatch-container' 32 | }, 33 | React.DOM.img({ 34 | height: 260, 35 | width: 260, 36 | alt: selectedSwatch.name, 37 | className: 'selected-swatch-image', 38 | src: selectedSwatch.image + '?wid=260&hei=260' 39 | }), 40 | 41 | React.DOM.strong({ 42 | className: 'selected-swatch-name' 43 | }, selectedSwatch.name) 44 | ); 45 | } 46 | })); 47 | 48 | Swatch.swatchGroupRenderer = mobxReact.observer(React.createClass({ 49 | displayName: 'swatchGroupRenderer', 50 | render: function () { 51 | 52 | var renderedSwatches = this.props.swatches.map(function (swatch) { 53 | return React.createElement(Swatch.swatchThumbnailRenderer, 54 | { 55 | key: swatch.materialId, 56 | swatch: swatch, 57 | setSelectedSwatch: this.props.setSelectedSwatch 58 | }); 59 | }, this); 60 | 61 | return React.DOM.div({ 62 | className: 'swatch-container' 63 | }, 64 | renderedSwatches 65 | ); 66 | } 67 | })); 68 | 69 | Swatch.swatchThumbnailRenderer = mobxReact.observer(React.createClass({ 70 | displayName: 'swatchThumbnailRenderer', 71 | render: function () { 72 | var swatch = this.props.swatch; 73 | 74 | var className = 'swatch' + (swatch.selected ? ' selected' : ''); 75 | 76 | return React.DOM.div({ 77 | className: className, 78 | key: swatch.materialId, 79 | onClick: this.swatchClickHandler 80 | }, 81 | React.DOM.img({ 82 | height: 31, 83 | width: 31, 84 | alt: swatch.name, 85 | src: swatch.image + '?wid=31&hei=31' 86 | }) 87 | ); 88 | }, 89 | swatchClickHandler: function () { 90 | console.log('swatch id: ' + this.props.swatch.materialId); 91 | this.props.setSelectedSwatch(this.props.swatch.materialId); 92 | } 93 | })); 94 | 95 | }()); -------------------------------------------------------------------------------- /04_mobx_stateless_func/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Swatch viewer non-mobx 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /04_mobx_stateless_func/js/swatch-renderer-viewer.js: -------------------------------------------------------------------------------- 1 | /** @namespace Swatch */ 2 | (function () { 3 | "use strict"; 4 | 5 | Swatch.ViewerFullRenderer = mobxReact.observer(function viewer_swatch (props) { 6 | 7 | var store = props.store; 8 | var selectedSwatch = store.selectedSwatch; 9 | 10 | return React.DOM.div({ 11 | className: 'swatch-viewer' 12 | }, 13 | React.DOM.h1(null, store.title), 14 | React.createElement(Swatch.selectedSwatchRenderer, { 15 | selectedSwatch: selectedSwatch 16 | }), 17 | React.createElement(Swatch.swatchGroupRenderer, { 18 | swatches: store.swatches, 19 | setSelectedSwatch: store.setSelectedSwatch 20 | }) 21 | ); 22 | }); 23 | 24 | Swatch.selectedSwatchRenderer = mobxReact.observer(function selectedSwatch_swatch (props) { 25 | 26 | var selectedSwatch = props.selectedSwatch; 27 | 28 | return React.DOM.div({ 29 | className: 'selected-swatch-container' 30 | }, 31 | React.DOM.img({ 32 | height: 260, 33 | width: 260, 34 | alt: selectedSwatch.name, 35 | className: 'selected-swatch-image', 36 | src: selectedSwatch.image + '?wid=260&hei=260' 37 | }), 38 | 39 | React.DOM.strong({ 40 | className: 'selected-swatch-name' 41 | }, selectedSwatch.name) 42 | ); 43 | 44 | }); 45 | 46 | Swatch.swatchGroupRenderer = mobxReact.observer(function swatchGroup_swatch (props) { 47 | 48 | return React.DOM.div({ 49 | className: 'swatch-container' 50 | }, 51 | props.swatches.map(function (swatch) { 52 | return React.createElement(Swatch.swatchThumbnailRenderer, { 53 | key: swatch.materialId, 54 | swatch: swatch, 55 | setSelectedSwatch: props.setSelectedSwatch 56 | }); 57 | }, this) 58 | ); 59 | }); 60 | 61 | Swatch.swatchThumbnailRenderer = mobxReact.observer(function swatchThumbnail_swatch (props) { 62 | var swatch = props.swatch; 63 | var className = 'swatch' + (swatch.selected ? ' selected' : ''); 64 | 65 | return React.DOM.div({ 66 | className: className, 67 | key: swatch.materialId, 68 | onClick: function () { 69 | props.setSelectedSwatch(swatch.materialId); 70 | } 71 | }, 72 | React.DOM.img({ 73 | height: 31, 74 | width: 31, 75 | alt: swatch.name, 76 | src: swatch.image + '?wid=31&hei=31' 77 | }) 78 | ); 79 | }); 80 | 81 | }()); -------------------------------------------------------------------------------- /05_mobx_perf/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 05 Swatch viewer non-mobx 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /05_mobx_perf/js/swatch-renderer-viewer.js: -------------------------------------------------------------------------------- 1 | /** @namespace Swatch */ 2 | (function () { 3 | "use strict"; 4 | 5 | Swatch.ViewerFullRenderer = mobxReact.observer(function viewer_swatch (props) { 6 | 7 | var store = props.store; 8 | var selectedSwatch = store.selectedSwatch; 9 | 10 | return React.DOM.div({ 11 | className: 'swatch-viewer', 12 | style: {width: '500px'} 13 | }, 14 | // React.createElement(mobxDevtools.default), 15 | React.DOM.h1(null, store.title), 16 | React.DOM.button({ 17 | onClick: function () { 18 | addRandomSwatches(500); 19 | } 20 | }, 'Add 500 swatches.'), 21 | React.DOM.button({ 22 | onClick: function () { 23 | store.toggleAnimation(); 24 | } 25 | }, 'Toggle Animation.'), 26 | React.createElement(Swatch.selectedSwatchRenderer, { 27 | selectedSwatch: selectedSwatch 28 | }), 29 | React.createElement(Swatch.animatableSwatchContainer, {store: store}) 30 | ); 31 | }); 32 | 33 | Swatch.animatableSwatchContainer = mobxReact.observer(function animatableSwatchContainer (props) { 34 | var store = props.store; 35 | return React.DOM.div({style: {width: '400px', position: 'absolute', transform: 'translate3d('+store.leftPosition + 'px, 0, 0)'}}, 36 | React.createElement(Swatch.swatchGroupRenderer, { 37 | swatches: store.swatches, 38 | setSelectedSwatch: store.setSelectedSwatch 39 | }) 40 | ); 41 | }); 42 | 43 | Swatch.selectedSwatchRenderer = mobxReact.observer(function selectedSwatch_swatch (props) { 44 | 45 | var selectedSwatch = props.selectedSwatch; 46 | 47 | return React.DOM.div({ 48 | className: 'selected-swatch-container' 49 | }, 50 | React.DOM.img({ 51 | height: 260, 52 | width: 260, 53 | alt: selectedSwatch.name, 54 | className: 'selected-swatch-image', 55 | src: selectedSwatch.image + '?wid=260&hei=260' 56 | }), 57 | 58 | React.DOM.strong({ 59 | className: 'selected-swatch-name' 60 | }, selectedSwatch.name) 61 | ); 62 | 63 | }); 64 | 65 | Swatch.swatchGroupRenderer = mobxReact.observer(function swatchGroup_swatch (props) { 66 | 67 | return React.DOM.div({ 68 | className: 'swatch-container' 69 | }, 70 | props.swatches.map(function (swatch) { 71 | return React.createElement(Swatch.swatchThumbnailRenderer, { 72 | key: swatch.materialId, 73 | swatch: swatch, 74 | setSelectedSwatch: props.setSelectedSwatch 75 | }); 76 | }, this) 77 | ); 78 | }); 79 | 80 | Swatch.swatchThumbnailRenderer = mobxReact.observer(function swatchThumbnail_swatch (props) { 81 | var swatch = props.swatch; 82 | var className = 'swatch' + (swatch.selected ? ' selected' : ''); 83 | 84 | return React.DOM.div({ 85 | className: className, 86 | key: swatch.materialId, 87 | onClick: function () { 88 | props.setSelectedSwatch(swatch.materialId); 89 | } 90 | }, 91 | React.DOM.img({ 92 | height: 31, 93 | width: 31, 94 | alt: swatch.name, 95 | src: swatch.image + '?wid=31&hei=31' 96 | }) 97 | ); 98 | }); 99 | 100 | }()); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # reactSwatchMobxDemo 2 | Simple progression from non-mobx to mobx 3 | 4 | ## 01 non MobX example 5 | 6 | Swatch viewer with basic top down rendering. 7 | 8 | ## 02 MobX backed data store with a top level autorun 9 | 10 | ## 03 MobX observer based rendering 11 | 12 | ## 04 stateless react components 13 | 14 | ## 05 perf demo 15 | -------------------------------------------------------------------------------- /reactSwatchMobxDemo.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /shared_assets/observable-swatch-store.js: -------------------------------------------------------------------------------- 1 | /** @namespace Swatch */ 2 | (function () { 3 | "use strict"; 4 | 5 | window.Swatch = {}; 6 | 7 | Swatch.SwatchStore = function (swatchJSONData) { 8 | 9 | mobx.extendObservable(this, { 10 | title: swatchJSONData.title, 11 | swatches: _.map(swatchJSONData.swatches, function (swatchData) { 12 | return mobx.extendObservable(swatchData, {selected: swatchData.selected}); 13 | }), 14 | selectedSwatch: function () { 15 | return _.find(this.swatches, 'selected'); 16 | } 17 | }); 18 | 19 | this.setSelectedSwatch = mobx.action('setSelectedSwatch', _.bind(function (materialId) { 20 | this.selectedSwatch.selected = false; 21 | _.find(this.swatches, {materialId: materialId}).selected = true; 22 | }, this)); 23 | 24 | }; 25 | 26 | }()); -------------------------------------------------------------------------------- /shared_assets/style.css: -------------------------------------------------------------------------------- 1 | html, body, div, span, applet, object, iframe, 2 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 3 | a, abbr, acronym, address, big, cite, code, 4 | del, dfn, em, font, img, ins, kbd, q, s, samp, 5 | small, strike, strong, sub, sup, tt, var, 6 | dl, dt, dd, ol, ul, li, 7 | fieldset, form, label, legend, 8 | table, caption, tbody, tfoot, thead, tr, th, td, menu { 9 | margin: 0; 10 | padding: 0; 11 | border: 0; 12 | outline: 0; 13 | font-size: 11px; 14 | font-family: Verdana, Arial, Helvetica, sans-serif; 15 | vertical-align: baseline; 16 | color: #333; 17 | } 18 | 19 | h1 { 20 | padding: 0; 21 | margin: 0 0 10px; 22 | color: #59452a; 23 | font-size: 24px; 24 | } 25 | 26 | .loading { 27 | height: 600px; 28 | width: 300px; 29 | line-height: 300px; 30 | text-align: center; 31 | font-size: 20px; 32 | font-weight: bold; 33 | } 34 | 35 | .error { 36 | height: 600px; 37 | width: 300px; 38 | line-height: 300px; 39 | text-align: center; 40 | font-size: 20px; 41 | font-weight: bold; 42 | color: red; 43 | } 44 | 45 | /* ------------------------------------- 46 | SWATCH DETAILS 47 | ------------------------------------- */ 48 | .swatch-viewer { 49 | position: relative; 50 | margin: 10px; 51 | width: 280px; 52 | } 53 | 54 | .swatch-image-container { 55 | display: inline-block; 56 | vertical-align: top; 57 | width: 260px; 58 | margin: 0 15px 15px 15px; 59 | } 60 | 61 | .swatch-viewer .selected-swatch-image { 62 | margin: 0 0 10px; 63 | } 64 | 65 | .swatch-viewer .selected-swatch-name { 66 | color: #56462f; 67 | font-size: 14px; 68 | display: block; 69 | margin: 0 0 10px; 70 | } 71 | 72 | .swatch-container { 73 | margin: 15px 0 10px; 74 | } 75 | 76 | .swatch-viewer .swatch { 77 | border: solid 1px #fff; 78 | display: inline-block; 79 | padding: 3px; 80 | margin: 1px; 81 | } 82 | 83 | .swatch-viewer .swatch img { 84 | height: 31px; 85 | width: 31px; 86 | vertical-align: top; 87 | } 88 | 89 | .swatch-viewer .swatch.selected, 90 | .swatch-viewer .swatch:hover { 91 | border-color: #cf7600; 92 | } -------------------------------------------------------------------------------- /shared_assets/swatch-data-1.js: -------------------------------------------------------------------------------- 1 | var swatchData1 = { 2 | "title": "Fabric Details", 3 | "swatches": [ 4 | { 5 | "name": "Tatum natural", 6 | "selected": false, 7 | "image": "http://s7d4.scene7.com/is/image/roomandboard/sw_tatumnatural", 8 | "materialId": 94776469 9 | }, 10 | { 11 | "name": "Tatum oatmeal", 12 | "selected": false, 13 | "image": "http://s7d4.scene7.com/is/image/roomandboard/sw_tatumoatmeal", 14 | "materialId": 94776470 15 | }, 16 | { 17 | "name": "Tatum lichen", 18 | "selected": false, 19 | "image": "http://s7d4.scene7.com/is/image/roomandboard/sw_tatumlichen", 20 | "materialId": 94776468 21 | }, 22 | { 23 | "name": "Tatum mustard", 24 | "selected": true, 25 | "image": "http://s7d4.scene7.com/is/image/roomandboard/sw_tatummustard", 26 | "materialId": 94781465 27 | }, 28 | { 29 | "name": "Tatum spice", 30 | "selected": false, 31 | "image": "http://s7d4.scene7.com/is/image/roomandboard/sw_tatumspice", 32 | "materialId": 94776472 33 | }, 34 | { 35 | "name": "Tatum grey", 36 | "selected": false, 37 | "image": "http://s7d4.scene7.com/is/image/roomandboard/sw_tatumgrey", 38 | "materialId": 94780735 39 | }, 40 | { 41 | "name": "Tatum gunmetal", 42 | "selected": false, 43 | "image": "http://s7d4.scene7.com/is/image/roomandboard/sw_tatumgunmetal", 44 | "materialId": 94776467 45 | }, 46 | { 47 | "name": "Tatum mink", 48 | "selected": false, 49 | "image": "http://s7d4.scene7.com/is/image/roomandboard/sw_tatummink", 50 | "materialId": 94780734 51 | }, 52 | { 53 | "name": "Tatum salt", 54 | "selected": false, 55 | "image": "http://s7d4.scene7.com/is/image/roomandboard/sw_tatumsalt", 56 | "materialId": 94776471 57 | } 58 | ] 59 | }; -------------------------------------------------------------------------------- /shared_assets/swatch-data-2.js: -------------------------------------------------------------------------------- 1 | var swatchData2 = { 2 | "title": "Material Details", 3 | "swatches": [ 4 | { 5 | "name": "Stainless steel", 6 | "selected": true, 7 | "image": "http://s7d4.scene7.com/is/image/roomandboard/sw_stainlesssteel", 8 | "materialId": 94772742 9 | }, 10 | { 11 | "name": "Natural steel", 12 | "selected": false, 13 | "image": "http://s7d4.scene7.com/is/image/roomandboard/sw_naturalsteel", 14 | "materialId": 94772743 15 | } 16 | ] 17 | }; --------------------------------------------------------------------------------