diff --git a/modules/backend/assets/js/october.dropdown.js b/modules/backend/assets/js/october.dropdown.js
deleted file mode 100644
index 928d54079..000000000
--- a/modules/backend/assets/js/october.dropdown.js
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Dropdown menus.
- *
- * This script customizes the Twitter Bootstrap drop-downs.
- *
- */
-+function ($) { "use strict";
-
- $(document).on('shown.bs.dropdown', '.dropdown', function(){
- $(document.body).addClass('dropdown-open')
-
- var dropdown = $('.dropdown-menu', this),
- dropdownContainer = $(this).data('dropdown-container')
-
- if ($('.dropdown-container', dropdown).length == 0) {
- var
- title = $('[data-toggle=dropdown]', this).text(),
- titleAttr = dropdown.data('dropdown-title'),
- timer = null;
-
- if (titleAttr !== undefined)
- title = titleAttr
-
- $('li:first-child', dropdown).addClass('first-item')
- dropdown.prepend($('
').addClass('dropdown-title').text(title))
-
- var
- container = $('').addClass('dropdown-container'),
- ul = $('')
-
- container.prepend(ul)
- ul.prepend(dropdown.children())
- dropdown.prepend(container)
-
- dropdown.on('touchstart', function(){
- window.setTimeout(function(){
- dropdown.addClass('scroll')
- }, 200)
- })
-
- dropdown.on('touchend', function(){
- window.setTimeout(function(){
- dropdown.removeClass('scroll')
- }, 200)
- })
-
- dropdown.on('click', 'a', function(){
- if (dropdown.hasClass('scroll'))
- return false
- })
- }
-
- if (dropdownContainer !== undefined && dropdownContainer == 'body') {
- $(this).data('oc.dropdown', dropdown)
- $(document.body).append(dropdown)
-
- dropdown.css({
- 'visibility': 'hidden',
- 'left': 0,
- 'top' : 0,
- 'display': 'block'
- })
-
- var targetOffset = $(this).offset(),
- targetHeight = $(this).height(),
- targetWidth = $(this).width(),
- position = {
- x: targetOffset.left,
- y: targetOffset.top + targetHeight
- },
- leftOffset = targetWidth < 30 ? -16 : 0,
- documentHeight = $(document).height(),
- dropdownHeight = dropdown.height()
-
- if ((dropdownHeight + position.y) > $(document).height()) {
- position.y = targetOffset.top - dropdownHeight - 12
- dropdown.addClass('top')
- } else
- dropdown.removeClass('top')
-
- dropdown.css({
- 'left': position.x + leftOffset,
- 'top': position.y,
- 'visibility': 'visible'
- })
- }
-
- if ($('.dropdown-overlay', document.body).length == 0)
- $(document.body).prepend($('').addClass('dropdown-overlay'));
- })
-
- $(document).on('hidden.bs.dropdown', '.dropdown', function(){
- var dropdown = $(this).data('oc.dropdown')
- if (dropdown !== undefined) {
- dropdown.css('display', 'none')
- $(this).append(dropdown)
- }
-
- $(document.body).removeClass('dropdown-open');
- })
-
-}(window.jQuery);
\ No newline at end of file
diff --git a/modules/backend/assets/js/october.js b/modules/backend/assets/js/october.js
index e6abb0925..faeba8af2 100644
--- a/modules/backend/assets/js/october.js
+++ b/modules/backend/assets/js/october.js
@@ -9,6 +9,7 @@
=require ../../../system/assets/ui/js/foundation.js
=require ../../../system/assets/ui/js/flashmessage.js
+=require ../../../system/assets/ui/js/dropdown.js
=require october.controls.js
=require october.utils.js
diff --git a/modules/backend/assets/less/core/variables.less b/modules/backend/assets/less/core/variables.less
index 69f4cefa6..be15a3e3a 100644
--- a/modules/backend/assets/less/core/variables.less
+++ b/modules/backend/assets/less/core/variables.less
@@ -145,11 +145,6 @@
@color-loading-indicator-text: #999999;
@color-stripe-loader: #0090c0;
-@color-dropdown-title-border: #c9c9c9;
-@color-dropdown-title-text: @dropdown-link-color;
-@color-dropdown-hover-color: #2f99da;
-@color-dropdown-hover-text: #ffffff;
-
@color-tab-inactive-text: #cccccc;
@color-tab-active-text: @color-text-title;
@color-tab-active-border: #5fb6f5;
diff --git a/modules/backend/assets/less/october.less b/modules/backend/assets/less/october.less
index 410b54293..d86ba4c45 100644
--- a/modules/backend/assets/less/october.less
+++ b/modules/backend/assets/less/october.less
@@ -24,6 +24,7 @@
@import "../../../system/assets/ui/less/form.less";
@import "../../../system/assets/ui/less/list.less";
@import "../../../system/assets/ui/less/progressbar.less";
+@import "../../../system/assets/ui/less/dropdown.less";
//
// Combines layout and vendor styles
diff --git a/modules/system/assets/ui/docs/dropdown.md b/modules/system/assets/ui/docs/dropdown.md
new file mode 100644
index 000000000..a5b6badac
--- /dev/null
+++ b/modules/system/assets/ui/docs/dropdown.md
@@ -0,0 +1,14 @@
+# Example
+
+
+
+
+
diff --git a/modules/system/assets/ui/js/dropdown.js b/modules/system/assets/ui/js/dropdown.js
new file mode 100644
index 000000000..e38c96591
--- /dev/null
+++ b/modules/system/assets/ui/js/dropdown.js
@@ -0,0 +1,252 @@
+/* ========================================================================
+ * Bootstrap: dropdown.js v3.1.1
+ * http://getbootstrap.com/javascript/#dropdowns
+ * ========================================================================
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // DROPDOWN CLASS DEFINITION
+ // =========================
+
+ var backdrop = '.dropdown-backdrop'
+ var toggle = '[data-toggle=dropdown]'
+ var Dropdown = function (element) {
+ $(element).on('click.bs.dropdown', this.toggle)
+ }
+
+ Dropdown.prototype.toggle = function (e) {
+ var $this = $(this)
+
+ if ($this.is('.disabled, :disabled')) return
+
+ var $parent = getParent($this)
+ var isActive = $parent.hasClass('open')
+
+ clearMenus()
+
+ if (!isActive) {
+ if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
+ // if mobile we use a backdrop because click events don't delegate
+ $('').insertAfter($(this)).on('click', clearMenus)
+ }
+
+ var relatedTarget = { relatedTarget: this }
+ $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
+
+ if (e.isDefaultPrevented()) return
+
+ $parent
+ .toggleClass('open')
+ .trigger('shown.bs.dropdown', relatedTarget)
+
+ $this.focus()
+ }
+
+ return false
+ }
+
+ Dropdown.prototype.keydown = function (e) {
+ if (!/(38|40|27)/.test(e.keyCode)) return
+
+ var $this = $(this)
+
+ e.preventDefault()
+ e.stopPropagation()
+
+ if ($this.is('.disabled, :disabled')) return
+
+ var $parent = getParent($this)
+ var isActive = $parent.hasClass('open')
+
+ if (!isActive || (isActive && e.keyCode == 27)) {
+ if (e.which == 27) $parent.find(toggle).focus()
+ return $this.click()
+ }
+
+ var desc = ' li:not(.divider):visible a'
+ var $items = $parent.find('[role=menu]' + desc + ', [role=listbox]' + desc)
+
+ if (!$items.length) return
+
+ var index = $items.index($items.filter(':focus'))
+
+ if (e.keyCode == 38 && index > 0) index-- // up
+ if (e.keyCode == 40 && index < $items.length - 1) index++ // down
+ if (!~index) index = 0
+
+ $items.eq(index).focus()
+ }
+
+ function clearMenus(e) {
+ $(backdrop).remove()
+ $(toggle).each(function () {
+ var $parent = getParent($(this))
+ var relatedTarget = { relatedTarget: this }
+ if (!$parent.hasClass('open')) return
+ $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
+ if (e.isDefaultPrevented()) return
+ $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
+ })
+ }
+
+ function getParent($this) {
+ var selector = $this.attr('data-target')
+
+ if (!selector) {
+ selector = $this.attr('href')
+ selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
+ }
+
+ var $parent = selector && $(selector)
+
+ return $parent && $parent.length ? $parent : $this.parent()
+ }
+
+
+ // DROPDOWN PLUGIN DEFINITION
+ // ==========================
+
+ var old = $.fn.dropdown
+
+ $.fn.dropdown = function (option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.dropdown')
+
+ if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
+ if (typeof option == 'string') data[option].call($this)
+ })
+ }
+
+ $.fn.dropdown.Constructor = Dropdown
+
+
+ // DROPDOWN NO CONFLICT
+ // ====================
+
+ $.fn.dropdown.noConflict = function () {
+ $.fn.dropdown = old
+ return this
+ }
+
+
+ // APPLY TO STANDARD DROPDOWN ELEMENTS
+ // ===================================
+
+ $(document)
+ .on('click.bs.dropdown.data-api', clearMenus)
+ .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
+ .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
+ .on('keydown.bs.dropdown.data-api', toggle + ', [role=menu], [role=listbox]', Dropdown.prototype.keydown)
+
+}(jQuery);
+
+
+
+/*
+ * Dropdown menus.
+ *
+ * This script customizes the Twitter Bootstrap drop-downs.
+ *
+ */
++function ($) { "use strict";
+
+ $(document).on('shown.bs.dropdown', '.dropdown', function(){
+ $(document.body).addClass('dropdown-open')
+
+ var dropdown = $('.dropdown-menu', this),
+ dropdownContainer = $(this).data('dropdown-container')
+
+ if ($('.dropdown-container', dropdown).length == 0) {
+ var
+ title = $('[data-toggle=dropdown]', this).text(),
+ titleAttr = dropdown.data('dropdown-title'),
+ timer = null;
+
+ if (titleAttr !== undefined)
+ title = titleAttr
+
+ $('li:first-child', dropdown).addClass('first-item')
+ dropdown.prepend($('').addClass('dropdown-title').text(title))
+
+ var
+ container = $('').addClass('dropdown-container'),
+ ul = $('')
+
+ container.prepend(ul)
+ ul.prepend(dropdown.children())
+ dropdown.prepend(container)
+
+ dropdown.on('touchstart', function(){
+ window.setTimeout(function(){
+ dropdown.addClass('scroll')
+ }, 200)
+ })
+
+ dropdown.on('touchend', function(){
+ window.setTimeout(function(){
+ dropdown.removeClass('scroll')
+ }, 200)
+ })
+
+ dropdown.on('click', 'a', function(){
+ if (dropdown.hasClass('scroll'))
+ return false
+ })
+ }
+
+ if (dropdownContainer !== undefined && dropdownContainer == 'body') {
+ $(this).data('oc.dropdown', dropdown)
+ $(document.body).append(dropdown)
+
+ dropdown.css({
+ 'visibility': 'hidden',
+ 'left': 0,
+ 'top' : 0,
+ 'display': 'block'
+ })
+
+ var targetOffset = $(this).offset(),
+ targetHeight = $(this).height(),
+ targetWidth = $(this).width(),
+ position = {
+ x: targetOffset.left,
+ y: targetOffset.top + targetHeight
+ },
+ leftOffset = targetWidth < 30 ? -16 : 0,
+ documentHeight = $(document).height(),
+ dropdownHeight = dropdown.height()
+
+ if ((dropdownHeight + position.y) > $(document).height()) {
+ position.y = targetOffset.top - dropdownHeight - 12
+ dropdown.addClass('top')
+ } else
+ dropdown.removeClass('top')
+
+ dropdown.css({
+ 'left': position.x + leftOffset,
+ 'top': position.y,
+ 'visibility': 'visible'
+ })
+ }
+
+ if ($('.dropdown-overlay', document.body).length == 0)
+ $(document.body).prepend($('').addClass('dropdown-overlay'));
+ })
+
+ $(document).on('hidden.bs.dropdown', '.dropdown', function(){
+ var dropdown = $(this).data('oc.dropdown')
+ if (dropdown !== undefined) {
+ dropdown.css('display', 'none')
+ $(this).append(dropdown)
+ }
+
+ $(document.body).removeClass('dropdown-open');
+ })
+
+}(window.jQuery);
\ No newline at end of file
diff --git a/modules/system/assets/ui/less/dropdown.base.less b/modules/system/assets/ui/less/dropdown.base.less
new file mode 100644
index 000000000..d853edd3d
--- /dev/null
+++ b/modules/system/assets/ui/less/dropdown.base.less
@@ -0,0 +1,189 @@
+// Dropdown arrow/caret
+.caret {
+ display: inline-block;
+ width: 0;
+ height: 0;
+ margin-left: 2px;
+ vertical-align: middle;
+ border-top: @caret-width-base solid;
+ border-right: @caret-width-base solid transparent;
+ border-left: @caret-width-base solid transparent;
+}
+
+// The dropdown wrapper (div)
+.dropdown {
+ position: relative;
+}
+
+// Prevent the focus on the dropdown toggle when closing dropdowns
+.dropdown-toggle:focus {
+ outline: 0;
+}
+
+// The dropdown menu (ul)
+.dropdown-menu {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ z-index: @zindex-dropdown;
+ display: none; // none by default, but block on "open" of the menu
+ float: left;
+ min-width: 160px;
+ padding: 5px 0;
+ margin: 2px 0 0; // override default ul
+ list-style: none;
+ font-size: @font-size-base;
+ background-color: @dropdown-bg;
+ border: 1px solid @dropdown-fallback-border; // IE8 fallback
+ border: 1px solid @dropdown-border;
+ border-radius: @border-radius-base;
+ .box-shadow(0 6px 12px rgba(0,0,0,.175));
+ background-clip: padding-box;
+
+ // Aligns the dropdown menu to right
+ //
+ // Deprecated as of 3.1.0 in favor of `.dropdown-menu-[dir]`
+ &.pull-right {
+ right: 0;
+ left: auto;
+ }
+
+ // Dividers (basically an hr) within the dropdown
+ .divider {
+ height: 1px;
+ margin: ((@line-height-computed / 2) - 1) 0;
+ overflow: hidden;
+ background-color: @dropdown-divider-bg;
+ }
+
+ // Links within the dropdown menu
+ > li > a {
+ display: block;
+ padding: 3px 20px;
+ clear: both;
+ font-weight: normal;
+ line-height: @line-height-base;
+ color: @dropdown-link-color;
+ white-space: nowrap; // prevent links from randomly breaking onto new lines
+ }
+}
+
+// Hover/Focus state
+.dropdown-menu > li > a {
+ &:hover,
+ &:focus {
+ text-decoration: none;
+ color: @dropdown-link-hover-color;
+ background-color: @dropdown-link-hover-bg;
+ }
+}
+
+// Active state
+.dropdown-menu > .active > a {
+ &,
+ &:hover,
+ &:focus {
+ color: @dropdown-link-active-color;
+ text-decoration: none;
+ outline: 0;
+ background-color: @dropdown-link-active-bg;
+ }
+}
+
+// Disabled state
+//
+// Gray out text and ensure the hover/focus state remains gray
+
+.dropdown-menu > .disabled > a {
+ &,
+ &:hover,
+ &:focus {
+ color: @dropdown-link-disabled-color;
+ }
+}
+// Nuke hover/focus effects
+.dropdown-menu > .disabled > a {
+ &:hover,
+ &:focus {
+ text-decoration: none;
+ background-color: transparent;
+ background-image: none; // Remove CSS gradient
+ filter: e(%("progid:DXImageTransform.Microsoft.gradient(enabled = false)"));
+ cursor: not-allowed;
+ }
+}
+
+// Open state for the dropdown
+.open {
+ // Show the menu
+ > .dropdown-menu {
+ display: block;
+ }
+
+ // Remove the outline when :focus is triggered
+ > a {
+ outline: 0;
+ }
+}
+
+// Menu positioning
+//
+// Add extra class to `.dropdown-menu` to flip the alignment of the dropdown
+// menu with the parent.
+.dropdown-menu-right {
+ left: auto; // Reset the default from `.dropdown-menu`
+ right: 0;
+}
+// With v3, we enabled auto-flipping if you have a dropdown within a right
+// aligned nav component. To enable the undoing of that, we provide an override
+// to restore the default dropdown menu alignment.
+//
+.dropdown-menu-left {
+ left: 0;
+ right: auto;
+}
+
+// Dropdown section headers
+.dropdown-header {
+ display: block;
+ padding: 3px 20px;
+ font-size: @font-size-small;
+ line-height: @line-height-base;
+ color: @dropdown-header-color;
+}
+
+// Backdrop to catch body clicks on mobile, etc.
+.dropdown-backdrop {
+ position: fixed;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ top: 0;
+ z-index: (@zindex-dropdown - 10);
+}
+
+// Right aligned dropdowns
+.pull-right > .dropdown-menu {
+ right: 0;
+ left: auto;
+}
+
+// Allow for dropdowns to go bottom up (aka, dropup-menu)
+//
+// Just add .dropup after the standard .dropdown class and you're set, bro.
+
+.dropup {
+ // Reverse the caret
+ .caret {
+ border-top: 0;
+ border-bottom: @caret-width-base solid;
+ content: "";
+ }
+ // Different positioning for bottom up menu
+ .dropdown-menu {
+ top: auto;
+ bottom: 100%;
+ margin-bottom: 1px;
+ }
+}
+
diff --git a/modules/backend/assets/less/controls/dropdown.less b/modules/system/assets/ui/less/dropdown.less
similarity index 85%
rename from modules/backend/assets/less/controls/dropdown.less
rename to modules/system/assets/ui/less/dropdown.less
index 1dbf70f34..de34c1947 100644
--- a/modules/backend/assets/less/controls/dropdown.less
+++ b/modules/system/assets/ui/less/dropdown.less
@@ -1,3 +1,43 @@
+
+//
+// Dependencies
+// --------------------------------------------------
+
+@import "global.less";
+@import "icon.less";
+
+//
+// Dropdowns
+// --------------------------------------------------
+
+@import "dropdown.base.less";
+
+@dropdown-bg: #fff;
+@dropdown-border: rgba(0,0,0,.15);
+@dropdown-fallback-border: #ccc;
+@dropdown-divider-bg: #e5e5e5;
+
+@dropdown-link-color: @gray-dark;
+@dropdown-link-hover-color: darken(@gray-dark, 5%);
+@dropdown-link-hover-bg: #f5f5f5;
+
+@dropdown-link-active-color: @component-active-color;
+@dropdown-link-active-bg: @component-active-bg;
+
+@dropdown-link-disabled-color: @gray-light;
+
+@dropdown-header-color: @gray-light;
+
+// Note: Deprecated @dropdown-caret-color as of v3.1.0
+@dropdown-caret-color: #000;
+
+
+@color-dropdown-title-border: #c9c9c9;
+@color-dropdown-title-text: @dropdown-link-color;
+@color-dropdown-hover-color: #2f99da;
+@color-dropdown-hover-text: #ffffff;
+
+
//
// Dropdowns
// --------------------------------------------------
diff --git a/modules/system/assets/ui/less/form.variables.less b/modules/system/assets/ui/less/form.variables.less
index e0b9805ad..91d6b7685 100644
--- a/modules/system/assets/ui/less/form.variables.less
+++ b/modules/system/assets/ui/less/form.variables.less
@@ -24,32 +24,6 @@
@input-group-addon-border-color: @input-border;
-//
-// Dropdowns
-// --------------------------------------------------
-
-@dropdown-bg: #fff;
-@dropdown-border: rgba(0,0,0,.15);
-@dropdown-fallback-border: #ccc;
-@dropdown-divider-bg: #e5e5e5;
-
-@dropdown-link-color: @gray-dark;
-@dropdown-link-hover-color: darken(@gray-dark, 5%);
-@dropdown-link-hover-bg: #f5f5f5;
-
-@dropdown-link-active-color: @component-active-color;
-@dropdown-link-active-bg: @component-active-bg;
-
-@dropdown-link-disabled-color: @gray-light;
-
-@dropdown-header-color: @gray-light;
-
-// Note: Deprecated @dropdown-caret-color as of v3.1.0
-@dropdown-caret-color: #000;
-
-
-
-
@form-breakpoint-min: 770px;
@form-breakpoint-max: (@form-breakpoint-min - 1);
diff --git a/modules/system/assets/ui/less/global.variables.less b/modules/system/assets/ui/less/global.variables.less
index f19043476..574b23d70 100644
--- a/modules/system/assets/ui/less/global.variables.less
+++ b/modules/system/assets/ui/less/global.variables.less
@@ -44,6 +44,18 @@
@screen-sm-max: (@screen-md-min - 1);
@screen-md-max: (@screen-lg-min - 1);
+//
+// Z-Indexes
+// --------------------------------------------------
+
+@zindex-navbar: 1000;
+@zindex-dropdown: 1000;
+@zindex-popover: 1010;
+@zindex-tooltip: 1030;
+@zindex-navbar-fixed: 1030;
+@zindex-modal-background: 1040;
+@zindex-modal: 1050;
+
//
// Typography
// --------------------------------------------------