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:51 UTC

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

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;