You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ro...@apache.org on 2015/03/02 17:52:50 UTC

[1/2] fauxton commit: updated refs/heads/master to a85eb42

Repository: couchdb-fauxton
Updated Branches:
  refs/heads/master 73bacedae -> a85eb42a1


extract components: header-toggle-button-component


Project: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/commit/b34a64eb
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/tree/b34a64eb
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/diff/b34a64eb

Branch: refs/heads/master
Commit: b34a64eb78167a95ba767125fb15a236404c87b7
Parents: 73baced
Author: Robert Kowalski <ro...@apache.org>
Authored: Fri Feb 27 14:02:14 2015 +0100
Committer: Robert Kowalski <ro...@apache.org>
Committed: Fri Feb 27 17:49:56 2015 +0100

----------------------------------------------------------------------
 .gitignore                                      |  1 +
 app/addons/components/README.md                 |  3 ++
 .../components/assets/less/components.less      |  3 ++
 .../assets/less/header-togglebutton.less        | 43 +++++++++++++++++
 app/addons/components/base.js                   | 22 +++++++++
 .../components/react-components.react.jsx       | 50 ++++++++++++++++++++
 .../tests/headerTogglebuttonSpec.react.jsx      | 41 ++++++++++++++++
 app/addons/documents/assets/less/header.less    | 44 -----------------
 app/addons/documents/header/header.react.jsx    | 29 ++----------
 app/addons/documents/tests/headerSpec.react.jsx | 19 --------
 settings.json.default                           |  1 +
 11 files changed, 168 insertions(+), 88 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/b34a64eb/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index 7d5a71f..f6f8a2e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,7 @@ app/load_addons.js
 app/addons/*
 !app/addons/activetasks
 !app/addons/config
+!app/addons/components
 !app/addons/plugins
 !app/addons/replication
 !app/addons/auth

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/b34a64eb/app/addons/components/README.md
----------------------------------------------------------------------
diff --git a/app/addons/components/README.md b/app/addons/components/README.md
new file mode 100644
index 0000000..01bf4b5
--- /dev/null
+++ b/app/addons/components/README.md
@@ -0,0 +1,3 @@
+# Components
+
+small building blocks for Fauxton built using React

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/b34a64eb/app/addons/components/assets/less/components.less
----------------------------------------------------------------------
diff --git a/app/addons/components/assets/less/components.less b/app/addons/components/assets/less/components.less
new file mode 100644
index 0000000..b85f5f7
--- /dev/null
+++ b/app/addons/components/assets/less/components.less
@@ -0,0 +1,3 @@
+@import "../../../../../assets/less/variables.less";
+
+@import "header-togglebutton.less";

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/b34a64eb/app/addons/components/assets/less/header-togglebutton.less
----------------------------------------------------------------------
diff --git a/app/addons/components/assets/less/header-togglebutton.less b/app/addons/components/assets/less/header-togglebutton.less
new file mode 100644
index 0000000..807a0ef
--- /dev/null
+++ b/app/addons/components/assets/less/header-togglebutton.less
@@ -0,0 +1,43 @@
+.header-control-box {
+  color: #666;
+  font-size: 13px;
+  line-height: 33px;
+  padding: 12px 20px 12px 20px;
+  height: @collapsedNavWidth;
+  background-color: transparent;
+  border: none;
+  border-right: 1px solid @btnBorder;
+  text-decoration: none;
+  float: left;
+  .icon {
+    font-size: 20px;
+  }
+}
+
+.header-control-box:hover {
+  .icon, span {
+    color: #e33f3b;
+  }
+}
+
+button.header-control-box:focus {
+  outline: 0;
+}
+
+.js-headerbar-togglebutton-selected {
+  .icon, span {
+    color: #e33f3b;
+  }
+}
+
+.control-toggle-alternative-header {
+  .icon {
+    padding: 0px 8px 0px 0px;
+  }
+}
+
+.header-control-square {
+  height: @collapsedNavWidth;
+  width: @collapsedNavWidth;
+  float: left;
+}

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/b34a64eb/app/addons/components/base.js
----------------------------------------------------------------------
diff --git a/app/addons/components/base.js b/app/addons/components/base.js
new file mode 100644
index 0000000..4a4a892
--- /dev/null
+++ b/app/addons/components/base.js
@@ -0,0 +1,22 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+define([
+
+],
+
+function () {
+  var Components = {};
+  Components.initialize = function () {};
+
+  return Components;
+});

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/b34a64eb/app/addons/components/react-components.react.jsx
----------------------------------------------------------------------
diff --git a/app/addons/components/react-components.react.jsx b/app/addons/components/react-components.react.jsx
new file mode 100644
index 0000000..c783e94
--- /dev/null
+++ b/app/addons/components/react-components.react.jsx
@@ -0,0 +1,50 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+define([
+  'app',
+  'api',
+
+  'react',
+],
+
+function (app, FauxtonAPI, React) {
+
+  var ToggleHeaderButton = React.createClass({
+    render: function () {
+      var iconClasses = 'icon ' + this.props.fonticon + ' ' + this.props.innerClasses,
+          containerClasses = 'button ' + this.props.containerClasses;
+
+      if (this.props.setEnabledClass) {
+        containerClasses = containerClasses + ' js-headerbar-togglebutton-selected';
+      }
+
+      return (
+        <button
+          title={this.props.title}
+          disabled={this.props.disabled}
+          onClick={this.props.toggleCallback}
+          className={containerClasses}
+          >
+          <i className={iconClasses}></i><span>{this.props.text}</span>
+        </button>
+      );
+    }
+  });
+
+  var Components = {
+    ToggleHeaderButton: ToggleHeaderButton
+  };
+
+  return Components;
+
+});

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/b34a64eb/app/addons/components/tests/headerTogglebuttonSpec.react.jsx
----------------------------------------------------------------------
diff --git a/app/addons/components/tests/headerTogglebuttonSpec.react.jsx b/app/addons/components/tests/headerTogglebuttonSpec.react.jsx
new file mode 100644
index 0000000..14523f3
--- /dev/null
+++ b/app/addons/components/tests/headerTogglebuttonSpec.react.jsx
@@ -0,0 +1,41 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+define([
+  'api',
+  'addons/components/react-components.react',
+
+  'testUtils',
+  'react'
+], function (FauxtonAPI, ReactComponents, utils, React) {
+
+  var assert = utils.assert;
+  var TestUtils = React.addons.TestUtils;
+
+  describe('Header Togglebutton', function () {
+    var container, toggleEl, toggleCallback;
+    beforeEach(function () {
+      container = document.createElement('div');
+      toggleCallback = sinon.spy();
+      toggleEl = TestUtils.renderIntoDocument(<ReactComponents.ToggleHeaderButton fonticon={'foo'}
+        classString={'bar'} toggleCallback={toggleCallback} />, container);
+    });
+
+    afterEach(function () {
+      React.unmountComponentAtNode(container);
+    });
+
+    it('should call the passed callback', function () {
+      TestUtils.Simulate.click(toggleEl.getDOMNode());
+      assert.ok(toggleCallback.calledOnce);
+    });
+  });
+});

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/b34a64eb/app/addons/documents/assets/less/header.less
----------------------------------------------------------------------
diff --git a/app/addons/documents/assets/less/header.less b/app/addons/documents/assets/less/header.less
index 9c3c15d..7675510 100644
--- a/app/addons/documents/assets/less/header.less
+++ b/app/addons/documents/assets/less/header.less
@@ -1,51 +1,7 @@
-.header-control-box {
-  color: #666;
-  font-size: 13px;
-  line-height: 33px;
-  padding: 12px 20px 12px 20px;
-  height: @collapsedNavWidth;
-  background-color: transparent;
-  border: none;
-  border-right: 1px solid @btnBorder;
-  text-decoration: none;
-  float: left;
-  .icon {
-    font-size: 20px;
-  }
-}
-
-.header-control-box:hover {
-  .icon, span {
-    color: #e33f3b;
-  }
-}
-
-button.header-control-box:focus {
-  outline: 0;
-}
-
-.js-headerbar-togglebutton-selected {
-  .icon, span {
-    color: #e33f3b;
-  }
-}
-
-.control-toggle-alternative-header {
-  .icon {
-    padding: 0px 8px 0px 0px;
-  }
-}
-
 .control-cancel {
   border-right: none;
 }
 
-.header-control-square {
-  height: @collapsedNavWidth;
-  width: @collapsedNavWidth;
-  float: left;
-}
-
 .alternative-header {
   float: left;
 }

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/b34a64eb/app/addons/documents/header/header.react.jsx
----------------------------------------------------------------------
diff --git a/app/addons/documents/header/header.react.jsx b/app/addons/documents/header/header.react.jsx
index faf46bc..efdf75f 100644
--- a/app/addons/documents/header/header.react.jsx
+++ b/app/addons/documents/header/header.react.jsx
@@ -15,36 +15,15 @@ define([
   'api',
   'react',
   'addons/documents/header/header.stores',
-  'addons/documents/header/header.actions'
+  'addons/documents/header/header.actions',
+  'addons/components/react-components.react',
 ],
 
-function (app, FauxtonAPI, React, Stores, Actions) {
+function (app, FauxtonAPI, React, Stores, Actions, ReactComponents) {
   var ReactCSSTransitionGroup = React.addons.CSSTransitionGroup;
   var headerBarStore = Stores.headerBarStore;
   var bulkDocumentHeaderStore = Stores.bulkDocumentHeaderStore;
-
-  // this will be a global component
-  var ToggleHeaderButton = React.createClass({
-    render: function () {
-      var iconClasses = 'icon ' + this.props.fonticon + ' ' + this.props.innerClasses,
-          containerClasses = 'button ' + this.props.containerClasses;
-
-      if (this.props.setEnabledClass) {
-        containerClasses = containerClasses + ' js-headerbar-togglebutton-selected';
-      }
-
-      return (
-        <button
-          title={this.props.title}
-          disabled={this.props.disabled}
-          onClick={this.props.toggleCallback}
-          className={containerClasses}
-          >
-          <i className={iconClasses}></i><span>{this.props.text}</span>
-        </button>
-      );
-    }
-  });
+  var ToggleHeaderButton = ReactComponents.ToggleHeaderButton;
 
   var BulkDocumentHeaderController = React.createClass({
     getStoreState: function () {

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/b34a64eb/app/addons/documents/tests/headerSpec.react.jsx
----------------------------------------------------------------------
diff --git a/app/addons/documents/tests/headerSpec.react.jsx b/app/addons/documents/tests/headerSpec.react.jsx
index 83edada..052bc9c 100644
--- a/app/addons/documents/tests/headerSpec.react.jsx
+++ b/app/addons/documents/tests/headerSpec.react.jsx
@@ -28,25 +28,6 @@ define([
   var assert = utils.assert;
   var TestUtils = React.addons.TestUtils;
 
-  describe('Header Togglebutton', function () {
-    var container, toggleEl, toggleCallback;
-    beforeEach(function () {
-      container = document.createElement('div');
-      toggleCallback = sinon.spy();
-      toggleEl = TestUtils.renderIntoDocument(<Views.ToggleHeaderButton fonticon={'foo'}
-        classString={'bar'} toggleCallback={toggleCallback} />, container);
-    });
-
-    afterEach(function () {
-      React.unmountComponentAtNode(container);
-    });
-
-    it('should call the passed callback', function () {
-      TestUtils.Simulate.click(toggleEl.getDOMNode());
-      assert.ok(toggleCallback.calledOnce);
-    });
-  });
-
   describe('Header Controller', function () {
     var container, toggleEl;
     beforeEach(function () {

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/b34a64eb/settings.json.default
----------------------------------------------------------------------
diff --git a/settings.json.default b/settings.json.default
index 35ed88e..775dfb9 100644
--- a/settings.json.default
+++ b/settings.json.default
@@ -1,6 +1,7 @@
 {
   "deps": [
   { "name": "fauxton" },
+  { "name": "components" },
   { "name": "databases" },
   { "name": "documents" },
   { "name": "activetasks" },


[2/2] fauxton commit: updated refs/heads/master to a85eb42

Posted by ro...@apache.org.
extract components: styled-select component


Project: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/commit/a85eb42a
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/tree/a85eb42a
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/diff/a85eb42a

Branch: refs/heads/master
Commit: a85eb42a1283c3fd5a69864eea466c7368b0b2e0
Parents: b34a64e
Author: Robert Kowalski <ro...@apache.org>
Authored: Fri Feb 27 17:43:54 2015 +0100
Committer: Robert Kowalski <ro...@apache.org>
Committed: Fri Feb 27 17:50:26 2015 +0100

----------------------------------------------------------------------
 .../components/assets/less/components.less      |   2 +
 .../components/assets/less/styled-select.less   |  35 +++
 .../components/react-components.react.jsx       |  25 +-
 .../components/tests/styledSelectSpec.react.jsx |  60 +++++
 app/addons/documents/assets/less/documents.less |   2 +-
 .../documents/assets/less/view-editor.less      | 209 ++++++++++++++++
 .../documents/assets/less/viewEditor.less       | 239 -------------------
 .../documents/index-editor/components.react.jsx |  24 +-
 .../tests/viewIndex.componentsSpec.react.jsx    |  38 ---
 9 files changed, 334 insertions(+), 300 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/a85eb42a/app/addons/components/assets/less/components.less
----------------------------------------------------------------------
diff --git a/app/addons/components/assets/less/components.less b/app/addons/components/assets/less/components.less
index b85f5f7..4eea4d8 100644
--- a/app/addons/components/assets/less/components.less
+++ b/app/addons/components/assets/less/components.less
@@ -1,3 +1,5 @@
 @import "../../../../../assets/less/variables.less";
 
 @import "header-togglebutton.less";
+@import "styled-select.less";
+

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/a85eb42a/app/addons/components/assets/less/styled-select.less
----------------------------------------------------------------------
diff --git a/app/addons/components/assets/less/styled-select.less b/app/addons/components/assets/less/styled-select.less
new file mode 100644
index 0000000..963334b
--- /dev/null
+++ b/app/addons/components/assets/less/styled-select.less
@@ -0,0 +1,35 @@
+.styled-select {
+  width: 200px;
+}
+
+.styled-select label {
+  margin: 0;
+}
+
+.styled-select select {
+  -webkit-appearance: none;
+  -moz-appearance: none;
+  appearance: none;
+  background-color: #e6e6e6;
+  border: 1px solid #b3b3b3;
+  height: 45px;
+  width: 200px;
+  text-indent: 4px;
+  height: 46px;
+}
+
+.styled-select select:-moz-focusring {
+  color: transparent;
+  text-shadow: 0 0 0 #000;
+}
+
+.styled-select select::-ms-expand {
+  display: none;
+}
+
+.styled-select i {
+  position: absolute;
+  right: 10px;
+  top: 12px;
+  pointer-events: none;
+}

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/a85eb42a/app/addons/components/react-components.react.jsx
----------------------------------------------------------------------
diff --git a/app/addons/components/react-components.react.jsx b/app/addons/components/react-components.react.jsx
index c783e94..b78646c 100644
--- a/app/addons/components/react-components.react.jsx
+++ b/app/addons/components/react-components.react.jsx
@@ -41,8 +41,31 @@ function (app, FauxtonAPI, React) {
     }
   });
 
+  // global component
+  var StyledSelect = React.createClass({
+    render: function () {
+      return (
+        <div className="styled-select">
+          <label htmlFor={this.props.selectId}>
+            <i className="fonticon-down-dir"></i>
+            <select
+              value={this.props.selectValue}
+              id={this.props.selectId}
+              className={this.props.selectValue}
+              onChange={this.props.selectChange}
+            >
+              {this.props.selectContent}
+            </select>
+          </label>
+        </div>
+      );
+    }
+  });
+
+
   var Components = {
-    ToggleHeaderButton: ToggleHeaderButton
+    ToggleHeaderButton: ToggleHeaderButton,
+    StyledSelect: StyledSelect
   };
 
   return Components;

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/a85eb42a/app/addons/components/tests/styledSelectSpec.react.jsx
----------------------------------------------------------------------
diff --git a/app/addons/components/tests/styledSelectSpec.react.jsx b/app/addons/components/tests/styledSelectSpec.react.jsx
new file mode 100644
index 0000000..7a3328a
--- /dev/null
+++ b/app/addons/components/tests/styledSelectSpec.react.jsx
@@ -0,0 +1,60 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+define([
+  'api',
+  'addons/components/react-components.react',
+
+  'testUtils',
+  'react'
+], function (FauxtonAPI, ReactComponents, utils, React) {
+
+  var assert = utils.assert;
+  var TestUtils = React.addons.TestUtils;
+
+  describe('styled select', function () {
+    var container, selectorEl, spy = sinon.spy();
+
+    beforeEach(function () {
+      container = document.createElement('div');
+
+      var selectContent = (
+        <optgroup label="Select a document">
+          <option value="new">New Design Document</option>
+          <option value="foo">New Design Document</option>
+        </optgroup>
+      );
+
+      selectorEl = TestUtils.renderIntoDocument(
+        <ReactComponents.StyledSelect
+          selectId="new-ddoc"
+          selectClass=""
+          selectContent={selectContent}
+          selectChange={spy} />,
+        container
+      );
+    });
+
+    afterEach(function () {
+      React.unmountComponentAtNode(container);
+    });
+
+    it('calls the callback on select', function () {
+      TestUtils.Simulate.change($(selectorEl.getDOMNode()).find('#new-ddoc')[0], {
+        target: {
+          value: 'new'
+        }
+      });
+      assert.ok(spy.calledOnce);
+    });
+
+  });
+});

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/a85eb42a/app/addons/documents/assets/less/documents.less
----------------------------------------------------------------------
diff --git a/app/addons/documents/assets/less/documents.less b/app/addons/documents/assets/less/documents.less
index 8e2df47..f7fcb20 100644
--- a/app/addons/documents/assets/less/documents.less
+++ b/app/addons/documents/assets/less/documents.less
@@ -14,7 +14,7 @@
 @import "../../../../../assets/less/bootstrap/variables.less";
 @import "../../../../../assets/less/bootstrap/mixins.less";
 @import "queryOptions.less";
-@import "viewEditor.less";
+@import "view-editor.less";
 @import "changes.less";
 @import "sidenav.less";
 @import "index-results.less";

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/a85eb42a/app/addons/documents/assets/less/view-editor.less
----------------------------------------------------------------------
diff --git a/app/addons/documents/assets/less/view-editor.less b/app/addons/documents/assets/less/view-editor.less
new file mode 100644
index 0000000..0afd29f
--- /dev/null
+++ b/app/addons/documents/assets/less/view-editor.less
@@ -0,0 +1,209 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+@import "../../../../../assets/less/variables.less";
+
+.editor-wrapper {
+
+
+  .define-view {
+    padding-bottom: 70px;
+  }
+
+  .define-view {
+    .help-link {
+      margin-left: 3px;
+    }
+  }
+  label {
+    font-size: 16px;
+  }
+  .bordered-box {
+    border-bottom: 1px solid #ccc;
+  }
+  .padded-box {
+    margin: 25px 30px;
+  }
+  .db-title {
+    color: @brandPrimary;
+    line-height: 30px;
+  }
+  #index-name {
+    height: 46px;
+    width: 200px;
+  }
+  .new-ddoc-input {
+    margin-top: 25px;
+    height: 46px;
+  }
+
+}
+
+// 940px grid without margin
+// -------------------------
+@gridColumnWidthNoMargin:         60px;
+@gridGutterWidthNoMargin:         0px;
+@gridRowWidthNoMargin:            (@gridColumns * @gridColumnWidthNoMargin) + (@gridGutterWidthNoMargin * (@gridColumns - 1));
+
+// 1200px min
+@gridColumnWidth1200NoMargin:     70px;
+@gridGutterWidth1200NoMargin:     0px;
+@gridRowWidth1200NoMargin:        (@gridColumns * @gridColumnWidth1200NoMargin) + (@gridGutterWidth1200NoMargin * (@gridColumns - 1));
+
+// 768px-979px
+@gridColumnWidth768NoMargin:      42px;
+@gridGutterWidth768NoMargin:      0px;
+@gridRowWidth768NoMargin:         (@gridColumns * @gridColumnWidth768NoMargin) + (@gridGutterWidth768NoMargin * (@gridColumns - 1));
+// Fluid grid
+// -------------------------
+@fluidGridColumnWidthNoMargin:    percentage(@gridColumnWidthNoMargin/@gridRowWidthNoMargin);
+@fluidGridGutterWidthNoMargin:    percentage(@gridGutterWidthNoMargin/@gridRowWidthNoMargin);
+// 1200px min
+@fluidGridColumnWidth1200NoMargin:     percentage(@gridColumnWidth1200NoMargin/@gridRowWidth1200NoMargin);
+@fluidGridGutterWidth1200NoMargin:     percentage(@gridGutterWidth1200NoMargin/@gridRowWidth1200NoMargin);
+// 768px-979px
+@fluidGridColumnWidth768NoMargin:      percentage(@gridColumnWidth768NoMargin/@gridRowWidth768NoMargin);
+@fluidGridGutterWidth768NoMargin:      percentage(@gridGutterWidth768NoMargin/@gridRowWidth768NoMargin);
+
+
+.two-pane > .fluid(@fluidGridColumnWidth1200NoMargin, @fluidGridGutterWidth1200NoMargin);
+
+.two-pane {
+
+  .core (@gridColumnWidth, @gridGutterWidth) {
+
+    .spanX (@index) when (@index > 0) {
+      .span@{index} { .span(@index); }
+      .spanX(@index - 1);
+    }
+    .spanX (0) {}
+
+    .offsetX (@index) when (@index > 0) {
+      .offset@{index} { .offset(@index); }
+      .offsetX(@index - 1);
+    }
+    .offsetX (0) {}
+
+    .offset (@columns) {
+      margin-left: (@gridColumnWidth * @columns) + (@gridGutterWidth * (@columns + 1));
+    }
+
+    .span (@columns) {
+      width: (@gridColumnWidth * @columns) + (@gridGutterWidth * (@columns - 1));
+    }
+
+    .row {
+      margin-left: @gridGutterWidth * -1;
+      .clearfix();
+    }
+
+    [class*="span"] {
+      float: left;
+      min-height: 1px; // prevent collapsing columns
+      margin-left: @gridGutterWidth;
+    }
+
+    // Set the container width, and override it for fixed navbars in media queries
+    .container,
+    .navbar-static-top .container,
+    .navbar-fixed-top .container,
+    .navbar-fixed-bottom .container { .span(@gridColumns); }
+
+    // generate .spanX and .offsetX
+    .spanX (@gridColumns);
+    .offsetX (@gridColumns);
+
+  }
+
+  .fluid (@fluidGridColumnWidth, @fluidGridGutterWidth) {
+
+    .spanX (@index) when (@index > 0) {
+      .span@{index} { .span(@index); }
+      .spanX(@index - 1);
+    }
+    .spanX (0) {}
+
+    .offsetX (@index) when (@index > 0) {
+      .offset@{index} { .offset(@index); }
+      .offset@{index}:first-child { .offsetFirstChild(@index); }
+      .offsetX(@index - 1);
+    }
+    .offsetX (0) {}
+
+    .offset (@columns) {
+      margin-left: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)) + (@fluidGridGutterWidth*2);
+      *margin-left: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)) - (.5 / @gridRowWidth * 100 * 1%) + (@fluidGridGutterWidth*2) - (.5 / @gridRowWidth * 100 * 1%);
+    }
+
+    .offsetFirstChild (@columns) {
+      margin-left: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)) + (@fluidGridGutterWidth);
+      *margin-left: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)) - (.5 / @gridRowWidth * 100 * 1%) + @fluidGridGutterWidth - (.5 / @gridRowWidth * 100 * 1%);
+    }
+
+    .span (@columns) {
+      width: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1));
+      *width: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)) - (.5 / @gridRowWidth * 100 * 1%);
+    }
+
+    .row-fluid {
+      width: 100%;
+      .clearfix();
+      [class*="span"] {
+        .input-block-level();
+        float: left;
+        margin-left: @fluidGridGutterWidth;
+        *margin-left: @fluidGridGutterWidth - (.5 / @gridRowWidth * 100 * 1%);
+      }
+      [class*="span"]:first-child {
+        margin-left: 0;
+      }
+
+      // Space grid-sized controls properly if multiple per line
+      .controls-row [class*="span"] + [class*="span"] {
+        margin-left: @fluidGridGutterWidth;
+      }
+
+      // generate .spanX and .offsetX
+      .spanX (@gridColumns);
+      .offsetX (@gridColumns);
+    }
+
+  }
+
+  .input(@gridColumnWidth, @gridGutterWidth) {
+
+    .spanX (@index) when (@index > 0) {
+      input.span@{index}, textarea.span@{index}, .uneditable-input.span@{index} { .span(@index); }
+      .spanX(@index - 1);
+    }
+    .spanX (0) {}
+
+    .span(@columns) {
+      width: ((@gridColumnWidth) * @columns) + (@gridGutterWidth * (@columns - 1)) - 14;
+    }
+
+    input,
+    textarea,
+    .uneditable-input {
+      margin-left: 0; // override margin-left from core grid system
+    }
+
+    // Space grid-sized controls properly if multiple per line
+    .controls-row [class*="span"] + [class*="span"] {
+      margin-left: @gridGutterWidth;
+    }
+
+    // generate .spanX
+    .spanX (@gridColumns);
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/a85eb42a/app/addons/documents/assets/less/viewEditor.less
----------------------------------------------------------------------
diff --git a/app/addons/documents/assets/less/viewEditor.less b/app/addons/documents/assets/less/viewEditor.less
deleted file mode 100644
index 6183537..0000000
--- a/app/addons/documents/assets/less/viewEditor.less
+++ /dev/null
@@ -1,239 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-@import "../../../../../assets/less/variables.less";
-
-.editor-wrapper {
-
-
-  .define-view {
-    padding-bottom: 70px;
-  }
-
-  .define-view {
-    .help-link {
-      margin-left: 3px;
-    }
-  }
-  label {
-    font-size: 16px;
-  }
-  .bordered-box {
-    border-bottom: 1px solid #ccc;
-  }
-  .padded-box {
-    margin: 25px 30px;
-  }
-  .db-title {
-    color: @brandPrimary;
-    line-height: 30px;
-  }
-  #index-name {
-    height: 46px;
-    width: 200px;
-  }
-  .new-ddoc-input {
-    margin-top: 25px;
-    height: 46px;
-  }
-
-  .styled-select {
-    width: 200px;
-  }
-  .styled-select label {
-    margin: 0;
-  }
-  .styled-select select {
-    -webkit-appearance: none;
-    -moz-appearance: none;
-    appearance: none;
-    background-color: #e6e6e6;
-    border: 1px solid #b3b3b3;
-    height: 45px;
-    width: 200px;
-    text-indent: 4px;
-    height: 46px;
-  }
-  .styled-select select:-moz-focusring {
-    color: transparent;
-    text-shadow: 0 0 0 #000;
-  }
-  .styled-select select::-ms-expand {
-    display: none;
-  }
-  .styled-select i {
-    position: absolute;
-    right: 10px;
-    top: 12px;
-    pointer-events: none;
-  }
-}
-
-// 940px grid without margin
-// -------------------------
-@gridColumnWidthNoMargin:         60px;
-@gridGutterWidthNoMargin:         0px;
-@gridRowWidthNoMargin:            (@gridColumns * @gridColumnWidthNoMargin) + (@gridGutterWidthNoMargin * (@gridColumns - 1));
-
-// 1200px min
-@gridColumnWidth1200NoMargin:     70px;
-@gridGutterWidth1200NoMargin:     0px;
-@gridRowWidth1200NoMargin:        (@gridColumns * @gridColumnWidth1200NoMargin) + (@gridGutterWidth1200NoMargin * (@gridColumns - 1));
-
-// 768px-979px
-@gridColumnWidth768NoMargin:      42px;
-@gridGutterWidth768NoMargin:      0px;
-@gridRowWidth768NoMargin:         (@gridColumns * @gridColumnWidth768NoMargin) + (@gridGutterWidth768NoMargin * (@gridColumns - 1));
-// Fluid grid
-// -------------------------
-@fluidGridColumnWidthNoMargin:    percentage(@gridColumnWidthNoMargin/@gridRowWidthNoMargin);
-@fluidGridGutterWidthNoMargin:    percentage(@gridGutterWidthNoMargin/@gridRowWidthNoMargin);
-// 1200px min
-@fluidGridColumnWidth1200NoMargin:     percentage(@gridColumnWidth1200NoMargin/@gridRowWidth1200NoMargin);
-@fluidGridGutterWidth1200NoMargin:     percentage(@gridGutterWidth1200NoMargin/@gridRowWidth1200NoMargin);
-// 768px-979px
-@fluidGridColumnWidth768NoMargin:      percentage(@gridColumnWidth768NoMargin/@gridRowWidth768NoMargin);
-@fluidGridGutterWidth768NoMargin:      percentage(@gridGutterWidth768NoMargin/@gridRowWidth768NoMargin);
-
-
-.two-pane > .fluid(@fluidGridColumnWidth1200NoMargin, @fluidGridGutterWidth1200NoMargin);
-
-.two-pane {
-
-  .core (@gridColumnWidth, @gridGutterWidth) {
-
-    .spanX (@index) when (@index > 0) {
-      .span@{index} { .span(@index); }
-      .spanX(@index - 1);
-    }
-    .spanX (0) {}
-
-    .offsetX (@index) when (@index > 0) {
-      .offset@{index} { .offset(@index); }
-      .offsetX(@index - 1);
-    }
-    .offsetX (0) {}
-
-    .offset (@columns) {
-      margin-left: (@gridColumnWidth * @columns) + (@gridGutterWidth * (@columns + 1));
-    }
-
-    .span (@columns) {
-      width: (@gridColumnWidth * @columns) + (@gridGutterWidth * (@columns - 1));
-    }
-
-    .row {
-      margin-left: @gridGutterWidth * -1;
-      .clearfix();
-    }
-
-    [class*="span"] {
-      float: left;
-      min-height: 1px; // prevent collapsing columns
-      margin-left: @gridGutterWidth;
-    }
-
-    // Set the container width, and override it for fixed navbars in media queries
-    .container,
-    .navbar-static-top .container,
-    .navbar-fixed-top .container,
-    .navbar-fixed-bottom .container { .span(@gridColumns); }
-
-    // generate .spanX and .offsetX
-    .spanX (@gridColumns);
-    .offsetX (@gridColumns);
-
-  }
-
-  .fluid (@fluidGridColumnWidth, @fluidGridGutterWidth) {
-
-    .spanX (@index) when (@index > 0) {
-      .span@{index} { .span(@index); }
-      .spanX(@index - 1);
-    }
-    .spanX (0) {}
-
-    .offsetX (@index) when (@index > 0) {
-      .offset@{index} { .offset(@index); }
-      .offset@{index}:first-child { .offsetFirstChild(@index); }
-      .offsetX(@index - 1);
-    }
-    .offsetX (0) {}
-
-    .offset (@columns) {
-      margin-left: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)) + (@fluidGridGutterWidth*2);
-      *margin-left: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)) - (.5 / @gridRowWidth * 100 * 1%) + (@fluidGridGutterWidth*2) - (.5 / @gridRowWidth * 100 * 1%);
-    }
-
-    .offsetFirstChild (@columns) {
-      margin-left: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)) + (@fluidGridGutterWidth);
-      *margin-left: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)) - (.5 / @gridRowWidth * 100 * 1%) + @fluidGridGutterWidth - (.5 / @gridRowWidth * 100 * 1%);
-    }
-
-    .span (@columns) {
-      width: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1));
-      *width: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)) - (.5 / @gridRowWidth * 100 * 1%);
-    }
-
-    .row-fluid {
-      width: 100%;
-      .clearfix();
-      [class*="span"] {
-        .input-block-level();
-        float: left;
-        margin-left: @fluidGridGutterWidth;
-        *margin-left: @fluidGridGutterWidth - (.5 / @gridRowWidth * 100 * 1%);
-      }
-      [class*="span"]:first-child {
-        margin-left: 0;
-      }
-
-      // Space grid-sized controls properly if multiple per line
-      .controls-row [class*="span"] + [class*="span"] {
-        margin-left: @fluidGridGutterWidth;
-      }
-
-      // generate .spanX and .offsetX
-      .spanX (@gridColumns);
-      .offsetX (@gridColumns);
-    }
-
-  }
-
-  .input(@gridColumnWidth, @gridGutterWidth) {
-
-    .spanX (@index) when (@index > 0) {
-      input.span@{index}, textarea.span@{index}, .uneditable-input.span@{index} { .span(@index); }
-      .spanX(@index - 1);
-    }
-    .spanX (0) {}
-
-    .span(@columns) {
-      width: ((@gridColumnWidth) * @columns) + (@gridGutterWidth * (@columns - 1)) - 14;
-    }
-
-    input,
-    textarea,
-    .uneditable-input {
-      margin-left: 0; // override margin-left from core grid system
-    }
-
-    // Space grid-sized controls properly if multiple per line
-    .controls-row [class*="span"] + [class*="span"] {
-      margin-left: @gridGutterWidth;
-    }
-
-    // generate .spanX
-    .spanX (@gridColumns);
-
-  }
-}

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/a85eb42a/app/addons/documents/index-editor/components.react.jsx
----------------------------------------------------------------------
diff --git a/app/addons/documents/index-editor/components.react.jsx b/app/addons/documents/index-editor/components.react.jsx
index 6d83683..83d4279 100644
--- a/app/addons/documents/index-editor/components.react.jsx
+++ b/app/addons/documents/index-editor/components.react.jsx
@@ -17,33 +17,15 @@ define([
   'addons/documents/index-editor/stores',
   'addons/documents/index-editor/actions',
   'addons/fauxton/components',
+  'addons/components/react-components.react',
   'plugins/beautify'
 ],
 
-function(app, FauxtonAPI, React, Stores, Actions, Components, beautifyHelper) {
+function (app, FauxtonAPI, React, Stores, Actions, Components, ReactComponents, beautifyHelper) {
   var indexEditorStore = Stores.indexEditorStore;
   var getDocUrl = app.helpers.getDocUrl;
+  var StyledSelect = ReactComponents.StyledSelect;
 
-  // global component
-  var StyledSelect = React.createClass({
-    render: function () {
-      return (
-        <div className="styled-select">
-          <label htmlFor={this.props.selectId}>
-            <i className="fonticon-down-dir"></i>
-            <select
-              value={this.props.selectValue}
-              id={this.props.selectId}
-              className={this.props.selectValue}
-              onChange={this.props.selectChange}
-            >
-              {this.props.selectContent}
-            </select>
-          </label>
-        </div>
-      );
-    }
-  });
 
   var DesignDocSelector = React.createClass({
 

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/a85eb42a/app/addons/documents/tests/viewIndex.componentsSpec.react.jsx
----------------------------------------------------------------------
diff --git a/app/addons/documents/tests/viewIndex.componentsSpec.react.jsx b/app/addons/documents/tests/viewIndex.componentsSpec.react.jsx
index 7f3eee9..4bad4a6 100644
--- a/app/addons/documents/tests/viewIndex.componentsSpec.react.jsx
+++ b/app/addons/documents/tests/viewIndex.componentsSpec.react.jsx
@@ -100,44 +100,6 @@ define([
     });
   });
 
-  describe('styled select', function () {
-    var container, selectorEl, spy = sinon.spy();
-
-    beforeEach(function () {
-      container = document.createElement('div');
-
-      var selectContent = (
-        <optgroup label="Select a document">
-          <option value="new">New Design Document</option>
-          <option value="foo">New Design Document</option>
-        </optgroup>
-      );
-
-      selectorEl = TestUtils.renderIntoDocument(
-        <Views.StyledSelect
-          selectId="new-ddoc"
-          selectClass=""
-          selectContent={selectContent}
-          selectChange={spy} />,
-        container
-      );
-    });
-
-    afterEach(function () {
-      React.unmountComponentAtNode(container);
-    });
-
-    it('calls the callback on select', function () {
-      TestUtils.Simulate.change($(selectorEl.getDOMNode()).find('#new-ddoc')[0], {
-        target: {
-          value: 'new'
-        }
-      });
-      assert.ok(spy.calledOnce);
-    });
-
-  });
-
   describe('design Doc Selector', function () {
     var container, selectorEl;