From d4662624a507343f841b741fa8406cacef2d6c91 Mon Sep 17 00:00:00 2001 From: prudho Date: Thu, 20 Dec 2018 13:01:59 +0100 Subject: [PATCH] refactor(slider): turn range into slider and add new features Closes #117 #149 #150 --- src/definitions/globals/site.js | 2 +- src/definitions/modules/range.js | 278 ---- src/definitions/modules/range.less | 207 --- src/definitions/modules/slider.js | 1216 +++++++++++++++++ src/definitions/modules/slider.less | 455 ++++++ src/semantic.less | 2 +- src/theme.config.example | 2 +- src/themes/default/modules/range.variables | 30 - .../{range.overrides => slider.overrides} | 2 +- src/themes/default/modules/slider.variables | 80 ++ tasks/config/admin/release.js | 2 +- tasks/config/defaults.js | 2 +- tasks/config/project/install.js | 2 +- 13 files changed, 1758 insertions(+), 522 deletions(-) delete mode 100644 src/definitions/modules/range.js delete mode 100644 src/definitions/modules/range.less create mode 100644 src/definitions/modules/slider.js create mode 100644 src/definitions/modules/slider.less delete mode 100644 src/themes/default/modules/range.variables rename src/themes/default/modules/{range.overrides => slider.overrides} (72%) create mode 100644 src/themes/default/modules/slider.variables diff --git a/src/definitions/globals/site.js b/src/definitions/globals/site.js index 11f76bbbfc..dfe072e0b4 100644 --- a/src/definitions/globals/site.js +++ b/src/definitions/globals/site.js @@ -452,7 +452,7 @@ $.site.settings = { 'modal', 'nag', 'popup', - 'range', + 'slider', 'rating', 'shape', 'sidebar', diff --git a/src/definitions/modules/range.js b/src/definitions/modules/range.js deleted file mode 100644 index df9eabba99..0000000000 --- a/src/definitions/modules/range.js +++ /dev/null @@ -1,278 +0,0 @@ -/*! - * # Semantic UI - Range - * http://github.com/semantic-org/semantic-ui/ - * - * - * Released under the MIT license - * http://opensource.org/licenses/MIT - * - */ - -;(function ( $, window, document, undefined ) { - - "use strict"; - - $.fn.range = function(parameters) { - - var - $allModules = $(this), - - offset = 10, - - query = arguments[0], - methodInvoked = (typeof query == 'string'), - queryArguments = [].slice.call(arguments, 1) - ; - - $allModules - .each(function() { - - var - settings = ( $.isPlainObject(parameters) ) - ? $.extend(true, {}, $.fn.range.settings, parameters) - : $.extend({}, $.fn.range.settings), - - namespace = settings.namespace, - min = settings.min, - max = settings.max, - step = settings.step, - start = settings.start, - input = settings.input, - - eventNamespace = '.' + namespace, - moduleNamespace = 'module-' + namespace, - - $module = $(this), - - element = this, - instance = $module.data(moduleNamespace), - - inner, - thumb, - trackLeft, - precision, - - module - ; - - module = { - - initialize: function() { - module.instantiate(); - module.sanitize(); - }, - - instantiate: function() { - instance = module; - $module - .data(moduleNamespace, module) - ; - $(element).html("
"); - inner = $(element).children('.inner')[0]; - thumb = $(element).find('.thumb')[0]; - trackLeft = $(element).find('.track-fill')[0]; - // find precision of step, used in calculating the value - module.determinePrecision(); - // set start location - module.setValuePosition(settings.start); - // event listeners - $(element).find('.track, .thumb, .inner').on('mousedown', function(event) { - event.stopImmediatePropagation(); - event.preventDefault(); - $(this).closest(".range").trigger('mousedown', event); - }); - $(element).find('.track, .thumb, .inner').on('touchstart', function(event) { - event.stopImmediatePropagation(); - event.preventDefault(); - $(this).closest(".range").trigger('touchstart', event); - }); - $(element).on('mousedown', function(event, originalEvent) { - module.rangeMousedown(event, false, originalEvent); - }); - $(element).on('touchstart', function(event, originalEvent) { - module.rangeMousedown(event, true, originalEvent); - }); - module.addVisibilityListener(element); - }, - - sanitize: function() { - if (typeof settings.min != 'number') { - settings.min = parseInt(settings.min) || 0; - } - if (typeof settings.max != 'number') { - settings.max = parseInt(settings.max) || false; - } - if (typeof settings.start != 'number') { - settings.start = parseInt(settings.start) || 0; - } - }, - - determinePrecision: function() { - var split = String(settings.step).split('.'); - var decimalPlaces; - if(split.length == 2) { - decimalPlaces = split[1].length; - } else { - decimalPlaces = 0; - } - precision = Math.pow(10, decimalPlaces); - }, - - determineValue: function(startPos, endPos, currentPos) { - var ratio = (currentPos - startPos) / (endPos - startPos); - var range = settings.max - settings.min; - var difference = Math.round(ratio * range / step) * step; - // Use precision to avoid ugly Javascript floating point rounding issues - // (like 35 * .01 = 0.35000000000000003) - difference = Math.round(difference * precision) / precision; - return difference + settings.min; - }, - - determinePosition: function(value) { - var ratio = (value - settings.min) / (settings.max - settings.min); - return Math.round(ratio * $(inner).width()) + $(trackLeft).position().left - offset; - }, - - setValue: function(newValue, triggeredByUser) { - if(typeof triggeredByUser === 'undefined') { - triggeredByUser = true; - } - if(settings.input) { - $(settings.input).val(newValue); - } - if(settings.onChange) { - settings.onChange(newValue, {triggeredByUser: triggeredByUser}); - } - }, - - setPosition: function(value) { - $(thumb).css({left: String(value) + 'px'}); - $(trackLeft).css({width: String(value + offset) + 'px'}); - }, - - rangeMousedown: function(mdEvent, isTouch, originalEvent) { - if( !$(element).hasClass('disabled') ) { - mdEvent.preventDefault(); - var left = $(inner).offset().left; - var right = left + $(inner).width(); - var pageX; - if(isTouch) { - pageX = originalEvent.originalEvent.touches[0].pageX; - } else { - pageX = (typeof mdEvent.pageX != 'undefined') ? mdEvent.pageX : originalEvent.pageX; - } - var value = module.determineValue(left, right, pageX); - if(pageX >= left && pageX <= right) { - module.setPosition(pageX - left - offset); - module.setValue(value); - } - var rangeMousemove = function(mmEvent) { - mmEvent.preventDefault(); - if(isTouch) { - pageX = mmEvent.originalEvent.touches[0].pageX; - } else { - pageX = mmEvent.pageX; - } - value = module.determineValue(left, right, pageX); - if(pageX >= left && pageX <= right) { - if(value >= settings.min && value <= settings.max) { - module.setPosition(pageX - left - offset); - module.setValue(value); - } - } - } - var rangeMouseup = function(muEvent) { - if(isTouch) { - $(document).off('touchmove', rangeMousemove); - $(document).off('touchend', rangeMouseup); - } else { - $(document).off('mousemove', rangeMousemove); - $(document).off('mouseup', rangeMouseup); - } - } - if(isTouch) { - $(document).on('touchmove', rangeMousemove); - $(document).on('touchend', rangeMouseup); - } - else { - $(document).on('mousemove', rangeMousemove); - $(document).on('mouseup', rangeMouseup); - } - } - }, - - setValuePosition: function(val, triggeredByUser) { - if(typeof triggeredByUser === 'undefined') { - triggeredByUser = true; - } - var position = module.determinePosition(val); - module.setPosition(position); - module.setValue(val, triggeredByUser); - }, - - invoke: function(query) { - switch(query) { - case 'set value': - if(queryArguments.length > 0) { - instance.setValuePosition(queryArguments[0], false); - } - break; - } - }, - - addVisibilityListener: function(elem) { - - // Add a mutation observer (https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) - // to detect when root invisible element is behing shown in order to initialize the thumb correctly - // when position and offets are available (https://stackoverflow.com/a/5974377) - - var observer = new MutationObserver(function(mutationList) { - if ($(elem).is(':visible')) { - observer.disconnect(); // Avoid infinite recursion because « module.setValuePosition » will trigger this observer - module.setValuePosition(settings.start); - } - }); - - var closestHiddenParent = $(elem).parentsUntil(':visible'); - - if (closestHiddenParent.length != 0) { - observer.observe(closestHiddenParent[closestHiddenParent.length - 1], {attributes: true}); - } - }, - - }; - - if(methodInvoked) { - if(instance === undefined) { - module.initialize(); - } - module.invoke(query); - } - else { - module.initialize(); - } - - }) - ; - - return this; - - }; - - $.fn.range.settings = { - - name : 'Range', - namespace : 'range', - - min : 0, - max : false, - step : 1, - start : 0, - input : false, - - onChange : function(value){}, - - }; - - -})( jQuery, window, document ); diff --git a/src/definitions/modules/range.less b/src/definitions/modules/range.less deleted file mode 100644 index c7380f6b28..0000000000 --- a/src/definitions/modules/range.less +++ /dev/null @@ -1,207 +0,0 @@ -/*! - * # Semantic UI - Range - * http://github.com/semantic-org/semantic-ui/ - * - * - * Released under the MIT license - * http://opensource.org/licenses/MIT - * - */ - - -/******************************* - Theme -*******************************/ - -@type : 'module'; -@element : 'range'; - -@import (multiple) '../../theme.config'; - -/******************************* - Range -*******************************/ - -.ui.range { - height: @barHeight; - width: @barWidth; -} - -.ui.range .inner { - margin: @innerMargin; - height: @barHeight; - position: relative; -} - -.ui.range .inner:hover { - cursor: @hoverCursor; -} - -.ui.range .inner .track { - position: absolute; - height: @trackHeight; - width: @trackWidth; - border-radius: @trackBorderRadius; - top: 9px; - left: 0; - background-color: @trackColor; -} - -.ui.range .inner .track-fill { - position: absolute; - height: @trackHeight; - width: 0; - border-radius: @trackBorderRadius; - top: 9px; - left: 0; - background-color: @trackFillColor; -} - -.ui.range .inner .thumb { - position: absolute; - top: 0; - left: 0; - height: @thumbHeight; - width: @thumbWidth; - background: @thumbBackground; - border-radius: @thumbBorderRadius; - box-shadow: @thumbBoxShadow; -} - - -/*-------------- - Inverted ----------------*/ - -.ui.inverted.range .inner .track { - background-color: @invertedTrackColor; -} - -.ui.inverted.range .inner .track-fill { - background-color: @invertedTrackFillColor; -} - - -/*-------------- - Colors ----------------*/ - -/* Red */ -.ui.red.range .inner .track-fill { - background-color: @red; -} -.ui.red.inverted.range .inner .track-fill { - background-color: @lightRed; -} - -/* Orange */ -.ui.orange.range .inner .track-fill { - background-color: @orange; -} -.ui.orange.inverted.range .inner .track-fill { - background-color: @lightOrange; -} - -/* Yellow */ -.ui.yellow.range .inner .track-fill { - background-color: @yellow; -} -.ui.yellow.inverted.range .inner .track-fill { - background-color: @lightYellow; -} - -/* Olive */ -.ui.olive.range .inner .track-fill { - background-color: @olive; -} -.ui.olive.inverted.range .inner .track-fill { - background-color: @lightOlive; -} - -/* Green */ -.ui.green.range .inner .track-fill { - background-color: @green; -} -.ui.green.inverted.range .inner .track-fill { - background-color: @lightGreen; -} - -/* Teal */ -.ui.teal.range .inner .track-fill { - background-color: @teal; -} -.ui.teal.inverted.range .inner .track-fill { - background-color: @lightTeal; -} - -/* Blue */ -.ui.blue.range .inner .track-fill { - background-color: @blue; -} -.ui.blue.inverted.range .inner .track-fill { - background-color: @lightBlue; -} - -/* Violet */ -.ui.violet.range .inner .track-fill { - background-color: @violet; -} -.ui.violet.inverted.range .inner .track-fill { - background-color: @lightViolet; -} - -/* Purple */ -.ui.purple.range .inner .track-fill { - background-color: @purple; -} -.ui.purple.inverted.range .inner .track-fill { - background-color: @lightPurple; -} - -/* Pink */ -.ui.pink.range .inner .track-fill { - background-color: @pink; -} -.ui.pink.inverted.range .inner .track-fill { - background-color: @lightPink; -} - -/* Brown */ -.ui.brown.range .inner .track-fill { - background-color: @brown; -} -.ui.brown.inverted.range .inner .track-fill { - background-color: @lightBrown; -} - -/* Grey */ -.ui.grey.range .inner .track-fill { - background-color: @grey; -} -.ui.grey.inverted.range .inner .track-fill { - background-color: @lightGrey; -} - -/* Black */ -.ui.black.range .inner .track-fill { - background-color: @black; -} -.ui.black.inverted.range .inner .track-fill { - background-color: @lightBlack; -} - - -/*-------------- - Disabled ----------------*/ -.ui.range.disabled { - opacity: @disabledOpacity; -} - -.ui.range.disabled .inner:hover { - cursor: auto; -} - -.ui.range.disabled .inner .track-fill { - background: @disabledTrackFillColor; -} diff --git a/src/definitions/modules/slider.js b/src/definitions/modules/slider.js new file mode 100644 index 0000000000..381a7147a3 --- /dev/null +++ b/src/definitions/modules/slider.js @@ -0,0 +1,1216 @@ +/*! + * # Semantic UI - Slider + * http://github.com/semantic-org/semantic-ui/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ( $, window, document, undefined ) { + +"use strict"; + +window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.fn.slider = function(parameters) { + + var + $allModules = $(this), + + moduleSelector = $allModules.selector || '', + + time = new Date().getTime(), + performance = [], + + query = arguments[0], + methodInvoked = (typeof query == 'string'), + queryArguments = [].slice.call(arguments, 1), + + alphabet = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'], + + SINGLE_STEP = 1, + BIG_STEP = 2, + NO_STEP = 0, + SINGLE_BACKSTEP = -1, + BIG_BACKSTEP = -2, + + // Used to manage document bound events. + // Use this so that we can distinguish between which document events are bound to which range. + currentRange = 0, + + returnedValue + ; + + $allModules + .each(function() { + + var + settings = ( $.isPlainObject(parameters) ) + ? $.extend(true, {}, $.fn.slider.settings, parameters) + : $.extend({}, $.fn.slider.settings), + + className = settings.className, + metadata = settings.metadata, + namespace = settings.namespace, + error = settings.error, + keys = settings.keys, + interpretLabel = settings.interpretLabel, + + isHover = false, + eventNamespace = '.' + namespace, + moduleNamespace = 'module-' + namespace, + + $module = $(this), + $currThumb, + $thumb, + $secondThumb, + $track, + $trackFill, + $labels, + + element = this, + instance = $module.data(moduleNamespace), + + documentEventID, + + value, + position, + secondPos, + offset, + precision, + isTouch, + + module + ; + + module = { + + initialize: function() { + module.debug('Initializing slider', settings); + + currentRange += 1; + documentEventID = currentRange; + + isTouch = module.setup.testOutTouch(); + module.setup.layout(); + module.setup.labels(); + + if(!module.is.disabled()) { + module.bind.events(); + } + + module.read.metadata(); + module.read.settings(); + + module.instantiate(); + }, + + instantiate: function() { + module.verbose('Storing instance of slider', module); + instance = module; + $module + .data(moduleNamespace, module) + ; + }, + + destroy: function() { + module.verbose('Destroying previous slider for', $module); + clearInterval(instance.interval); + module.unbind.events(); + module.unbind.slidingEvents(); + $module.removeData(moduleNamespace); + instance = undefined; + }, + + setup: { + layout: function() { + if( $module.attr('tabindex') === undefined) { + $module.attr('tabindex', 0); + } + if($module.find('.inner').length == 0) { + $module.append("
" + + "
" + + "
" + + "
" + + "
"); + } + precision = module.get.precision(); + $thumb = $module.find('.thumb:not(.second)'); + $currThumb = $thumb; + if(module.is.range()) { + if($module.find('.thumb.second').length == 0) { + $module.find('.inner').append("
"); + } + $secondThumb = $module.find('.thumb.second'); + } + $track = $module.find('.track'); + $trackFill = $module.find('.track-fill'); + offset = $thumb.width() / 2; + }, + labels: function() { + if(module.is.labeled()) { + $labels = $module.find('.labels:not(.auto)'); + if($labels.length != 0) { + module.setup.customLabel(); + } else { + module.setup.autoLabel(); + } + + if (settings.showLabelTicks) { + $module.addClass(className.ticked) + } + } + }, + testOutTouch: function() { + try { + document.createEvent('TouchEvent'); + return true; + } catch (e) { + return false; + } + }, + customLabel: function() { + var + $children = $labels.find('.label'), + numChildren = $children.length, + min = module.get.min(), + max = module.get.max(), + ratio + ; + $children.each(function(index) { + var + $child = $(this), + attrValue = $child.attr('data-value') + ; + if(attrValue) { + attrValue = attrValue > max ? max : attrValue < min ? min : attrValue; + ratio = (attrValue - min) / (max - min); + } else { + ratio = (index + 1) / (numChildren + 1); + } + module.update.labelPosition(ratio, $(this)); + }); + }, + autoLabel: function() { + if(module.get.step() != 0) { + $labels = $module.find('.labels'); + if($labels.length != 0) { + $labels.empty(); + } + else { + $labels = $module.append('').find('.labels'); + } + for(var i = 0, len = module.get.numLabels(); i <= len; i++) { + var + labelText = module.get.label(i), + $label = (labelText !== "") ? $('
  • ' + labelText + '
  • ') : null, + ratio = i / len + ; + if($label) { + module.update.labelPosition(ratio, $label); + $labels.append($label); + } + } + } + } + }, + + bind: { + events: function() { + module.bind.globalKeyboardEvents(); + module.bind.keyboardEvents(); + module.bind.mouseEvents(); + if(module.is.touch()) { + module.bind.touchEvents(); + } + }, + keyboardEvents: function() { + module.verbose('Binding keyboard events'); + $module.on('keydown' + eventNamespace, module.event.keydown); + }, + globalKeyboardEvents: function() { + $(document).on('keydown' + eventNamespace + documentEventID, module.event.activateFocus); + }, + mouseEvents: function() { + module.verbose('Binding mouse events'); + $module.find('.track, .thumb, .inner').on('mousedown' + eventNamespace, function(event) { + event.stopImmediatePropagation(); + event.preventDefault(); + module.event.down(event); + }); + $module.on('mousedown' + eventNamespace, module.event.down); + $module.on('mouseenter' + eventNamespace, function(event) { + isHover = true; + }); + $module.on('mouseleave' + eventNamespace, function(event) { + isHover = false; + }); + }, + touchEvents: function() { + module.verbose('Binding touch events'); + $module.find('.track, .thumb, .inner').on('touchstart' + eventNamespace, function(event) { + event.stopImmediatePropagation(); + event.preventDefault(); + module.event.down(event); + }); + $module.on('touchstart' + eventNamespace, module.event.down); + }, + slidingEvents: function() { + // these don't need the identifier because we only ever want one of them to be registered with document + module.verbose('Binding page wide events while handle is being draged'); + if(module.is.touch()) { + $(document).on('touchmove' + eventNamespace, module.event.move); + $(document).on('touchend' + eventNamespace, module.event.up); + } + else { + $(document).on('mousemove' + eventNamespace, module.event.move); + $(document).on('mouseup' + eventNamespace, module.event.up); + } + } + }, + + unbind: { + events: function() { + $module.find('.track, .thumb, .inner').off('mousedown' + eventNamespace); + $module.find('.track, .thumb, .inner').off('touchstart' + eventNamespace); + $module.off('mousedown' + eventNamespace); + $module.off('mouseenter' + eventNamespace); + $module.off('mouseleave' + eventNamespace); + $module.off('touchstart' + eventNamespace); + $module.off('keydown' + eventNamespace); + $module.off('focusout' + eventNamespace); + $(document).off('keydown' + eventNamespace + documentEventID, module.event.activateFocus); + }, + slidingEvents: function() { + if(module.is.touch()) { + $(document).off('touchmove' + eventNamespace); + $(document).off('touchend' + eventNamespace); + } else { + $(document).off('mousemove' + eventNamespace); + $(document).off('mouseup' + eventNamespace); + } + }, + }, + + event: { + down: function(event, originalEvent) { + event.preventDefault(); + if(module.is.range()) { + var + eventPos = module.determine.eventPos(event, originalEvent), + newPos = module.determine.pos(eventPos) + ; + $currThumb = module.determine.closestThumb(newPos); + } + if(!module.is.disabled()) { + module.bind.slidingEvents(); + } + }, + move: function(event, originalEvent) { + event.preventDefault(); + var value = module.determine.valueFromEvent(event, originalEvent); + if(module.get.step() == 0 || module.is.smooth()) { + var + thumbVal = module.thumbVal, + secondThumbVal = module.secondThumbVal, + thumbSmoothVal = module.determine.smoothValueFromEvent(event, originalEvent) + ; + if(!$currThumb.hasClass('second')) { + thumbVal = value; + } else { + secondThumbVal = value; + } + value = Math.abs(thumbVal - (secondThumbVal || 0)); + module.update.position(thumbSmoothVal); + settings.onMove.call(element, value, thumbVal, secondThumbVal); + } else { + module.update.value(value, function(value, thumbVal, secondThumbVal) { + settings.onMove.call(element, value, thumbVal, secondThumbVal); + }); + } + }, + up: function(event, originalEvent) { + event.preventDefault(); + var value = module.determine.valueFromEvent(event, originalEvent); + module.set.value(value); + module.unbind.slidingEvents(); + }, + keydown: function(event, first) { + if(module.is.focused()) { + $(document).trigger(event); + } + if(first || module.is.focused()) { + var step = module.determine.keyMovement(event); + if(step != NO_STEP) { + event.preventDefault(); + switch(step) { + case SINGLE_STEP: + module.takeStep(); + break; + case BIG_STEP: + module.takeStep(module.get.multiplier()); + break; + case SINGLE_BACKSTEP: + module.backStep(); + break; + case BIG_BACKSTEP: + module.backStep(module.get.multiplier()); + break; + } + } + } + }, + activateFocus: function(event) { + if(!module.is.focused() && module.is.hover() && module.determine.keyMovement(event) != NO_STEP) { + event.preventDefault(); + module.event.keydown(event, true); + $module.focus(); + } + }, + }, + + resync: function() { + module.verbose('Resyncing thumb position based on value'); + if(module.is.range()) { + module.update.position(module.secondThumbVal, $secondThumb); + } + module.update.position(module.thumbVal, $thumb); + module.setup.labels(); + }, + takeStep: function(multiplier) { + var + multiplier = multiplier != undefined ? multiplier : 1, + step = module.get.step(), + currValue = module.get.currentThumbValue() + ; + module.verbose('Taking a step'); + if(step > 0) { + module.set.value(currValue + step * multiplier); + } else if (step == 0){ + var + precision = module.get.precision(), + newValue = currValue + (multiplier/precision) + ; + module.set.value(Math.round(newValue * precision) / precision); + } + }, + + backStep: function(multiplier) { + var + multiplier = multiplier != undefined ? multiplier : 1, + step = module.get.step(), + currValue = module.get.currentThumbValue() + ; + module.verbose('Going back a step'); + if(step > 0) { + module.set.value(currValue - step * multiplier); + } else if (step == 0) { + var + precision = module.get.precision(), + newValue = currValue - (multiplier/precision) + ; + module.set.value(Math.round(newValue * precision) / precision); + } + }, + + is: { + range: function() { + return $module.hasClass(settings.className.range); + }, + hover: function() { + return isHover; + }, + focused: function() { + return $module.is(':focus'); + }, + disabled: function() { + return $module.hasClass(settings.className.disabled); + }, + labeled: function() { + return $module.hasClass(settings.className.labeled); + }, + reversed: function() { + return $module.hasClass(settings.className.reversed); + }, + vertical: function() { + return $module.hasClass(settings.className.vertical); + }, + smooth: function() { + return settings.smooth || $module.hasClass(settings.className.smooth); + }, + touch: function() { + return isTouch; + } + }, + + get: { + trackOffset: function() { + if (module.is.vertical()) { + return $track.offset().top; + } else { + return $track.offset().left; + } + }, + trackLength: function() { + if (module.is.vertical()) { + return $track.height(); + } else { + return $track.width(); + } + }, + trackLeft: function() { + if (module.is.vertical()) { + return $track.position().top; + } else { + return $track.position().left; + } + }, + trackStartPos: function() { + return module.is.reversed() ? module.get.trackLeft() + module.get.trackLength() : module.get.trackLeft(); + }, + trackEndPos: function() { + return module.is.reversed() ? module.get.trackLeft() : module.get.trackLeft() + module.get.trackLength(); + }, + trackStartMargin: function () { + var margin; + if (module.is.vertical()) { + margin = module.is.reversed() ? $module.css('padding-bottom') : $module.css('padding-top'); + } else { + margin = module.is.reversed() ? $module.css('padding-right') : $module.css('padding-left'); + } + return margin || '0px'; + }, + trackEndMargin: function () { + var margin; + if (module.is.vertical()) { + margin = module.is.reversed() ? $module.css('padding-top') : $module.css('padding-bottom'); + } else { + margin = module.is.reversed() ? $module.css('padding-left') : $module.css('padding-right'); + } + return margin || '0px'; + }, + precision: function() { + var + decimalPlaces, + step = module.get.step() + ; + if(step != 0) { + var split = String(step).split('.'); + if(split.length == 2) { + decimalPlaces = split[1].length; + } else { + decimalPlaces = 0; + } + } else { + decimalPlaces = settings.decimalPlaces; + } + var precision = Math.pow(10, decimalPlaces); + module.debug('Precision determined', precision); + return precision; + }, + min: function() { + return settings.min; + }, + max: function() { + return settings.max; + }, + step: function() { + return settings.step; + }, + numLabels: function() { + var value = Math.round((module.get.max() - module.get.min()) / module.get.step()); + module.debug('Determined that their should be ' + value + ' labels'); + return value; + }, + labelType: function() { + return settings.labelType; + }, + label: function(value) { + if(interpretLabel) { + return interpretLabel(value); + } + + switch (settings.labelType) { + case settings.labelTypes.number: + return (value * module.get.step()) + module.get.min(); + case settings.labelTypes.letter: + return alphabet[(value) % 26]; + default: + return value; + } + }, + value: function() { + return value; + }, + currentThumbValue: function() { + return $currThumb.hasClass('second') ? module.secondThumbVal : module.thumbVal; + }, + thumbValue: function(which) { + switch(which) { + case 'second': + if(module.is.range()) { + return module.secondThumbVal; + } + else { + module.error(error.notrange); + break; + } + case 'first': + default: + return module.thumbVal; + } + }, + multiplier: function() { + return settings.pageMultiplier; + }, + thumbPosition: function(which) { + switch(which) { + case 'second': + if(module.is.range()) { + return secondPos; + } + else { + module.error(error.notrange); + break; + } + case 'first': + default: + return position; + } + } + }, + + determine: { + pos: function(pagePos) { + return module.is.reversed() + ? + module.get.trackStartPos() - pagePos + module.get.trackOffset() + : + pagePos - module.get.trackOffset() - module.get.trackStartPos() + ; + }, + closestThumb: function(eventPos) { + var + thumbPos = parseFloat(module.determine.thumbPos($thumb)), + thumbDelta = Math.abs(eventPos - thumbPos), + secondThumbPos = parseFloat(module.determine.thumbPos($secondThumb)), + secondThumbDelta = Math.abs(eventPos - secondThumbPos) + ; + return thumbDelta <= secondThumbDelta ? $thumb : $secondThumb; + }, + closestThumbPos: function(eventPos) { + var + thumbPos = parseFloat(module.determine.thumbPos($thumb)), + thumbDelta = Math.abs(eventPos - thumbPos), + secondThumbPos = parseFloat(module.determine.thumbPos($secondThumb)), + secondThumbDelta = Math.abs(eventPos - secondThumbPos) + ; + return thumbDelta <= secondThumbDelta ? thumbPos : secondThumbPos; + }, + thumbPos: function($element) { + var pos = + module.is.vertical() + ? + module.is.reversed() ? $element.css('bottom') : $element.css('top') + : + module.is.reversed() ? $element.css('right') : $element.css('left') + ; + return pos; + }, + positionFromValue: function(value) { + var + min = module.get.min(), + max = module.get.max(), + value = value > max ? max : value < min ? min : value, + trackLength = module.get.trackLength(), + ratio = (value - min) / (max - min), + position = Math.round(ratio * trackLength) + ; + module.verbose('Determined position: ' + position + ' from value: ' + value); + return position; + }, + positionFromRatio: function(ratio) { + var + trackLength = module.get.trackLength(), + step = module.get.step(), + position = Math.round(ratio * trackLength), + adjustedPos = (step == 0) ? position : Math.round(position / step) * step + ; + return adjustedPos; + }, + valueFromEvent: function(event, originalEvent) { + var + eventPos = module.determine.eventPos(event, originalEvent), + newPos = module.determine.pos(eventPos), + value + ; + if(eventPos < module.get.trackOffset()) { + value = module.is.reversed() ? module.get.max() : module.get.min(); + } else if(eventPos > module.get.trackOffset() + module.get.trackLength()) { + value = module.is.reversed() ? module.get.min() : module.get.max(); + } else { + value = module.determine.value(newPos); + } + return value; + }, + smoothValueFromEvent: function(event, originalEvent) { + var + min = module.get.min(), + max = module.get.max(), + trackLength = module.get.trackLength(), + eventPos = module.determine.eventPos(event, originalEvent), + newPos = eventPos - module.get.trackOffset(), + ratio, + value + ; + newPos = newPos < 0 ? 0 : newPos > trackLength ? trackLength : newPos; + ratio = newPos / trackLength; + if (module.is.reversed()) { + ratio = 1 - ratio; + } + value = ratio * (max - min) + min; + return value; + }, + eventPos: function(event, originalEvent) { + if(module.is.touch()) { + var + touchY = event.changedTouches[0].pageY || event.touches[0].pageY, + touchX = event.changedTouches[0].pageX || event.touches[0].pageX + ; + return module.is.vertical() ? touchY : touchX; + } + var + clickY = event.pageY || originalEvent.pageY, + clickX = event.pageX || originalEvent.pageX + ; + return module.is.vertical() ? clickY : clickX; + }, + value: function(position) { + var + startPos = module.is.reversed() ? module.get.trackEndPos() : module.get.trackStartPos(), + endPos = module.is.reversed() ? module.get.trackStartPos() : module.get.trackEndPos(), + ratio = (position - startPos) / (endPos - startPos), + range = module.get.max() - module.get.min(), + step = module.get.step(), + value = (ratio * range), + difference = (step == 0) ? value : Math.round(value / step) * step + ; + module.verbose('Determined value based upon position: ' + position + ' as: ' + value); + if(value != difference) { + module.verbose('Rounding value to closest step: ' + difference); + } + // Use precision to avoid ugly Javascript floating point rounding issues + // (like 35 * .01 = 0.35000000000000003) + difference = Math.round(difference * precision) / precision; + module.verbose('Cutting off additional decimal places'); + return difference + module.get.min(); + }, + keyMovement: function(event) { + var + key = event.which, + downArrow = + module.is.vertical() + ? + module.is.reversed() ? keys.downArrow : keys.upArrow + : + keys.downArrow + , + upArrow = + module.is.vertical() + ? + module.is.reversed() ? keys.upArrow : keys.downArrow + : + keys.upArrow + , + leftArrow = + !module.is.vertical() + ? + module.is.reversed() ? keys.rightArrow : keys.leftArrow + : + keys.leftArrow + , + rightArrow = + !module.is.vertical() + ? + module.is.reversed() ? keys.leftArrow : keys.rightArrow + : + keys.rightArrow + ; + if(key == downArrow || key == leftArrow) { + return SINGLE_BACKSTEP; + } else if(key == upArrow || key == rightArrow) { + return SINGLE_STEP; + } else if (key == keys.pageDown) { + return BIG_BACKSTEP; + } else if (key == keys.pageUp) { + return BIG_STEP; + } else { + return NO_STEP; + } + } + }, + + handleNewValuePosition: function(val) { + var + min = module.get.min(), + max = module.get.max(), + newPos + ; + if (val <= min) { + val = min; + } else if (val >= max) { + val = max; + } + newPos = module.determine.positionFromValue(val); + return newPos; + }, + + set: { + value: function(newValue) { + module.update.value(newValue, function(value, thumbVal, secondThumbVal) { + settings.onChange.call(element, value, thumbVal, secondThumbVal); + settings.onMove.call(element, value, thumbVal, secondThumbVal); + }); + }, + rangeValue: function(first, second) { + if(module.is.range()) { + var + min = module.get.min(), + max = module.get.max() + ; + if (first <= min) { + first = min; + } else if(first >= max){ + first = max; + } + if (second <= min) { + second = min; + } else if(second >= max){ + second = max; + } + module.thumbVal = first; + module.secondThumbVal = second; + value = Math.abs(module.thumbVal - module.secondThumbVal); + module.update.position(module.thumbVal, $thumb); + module.update.position(module.secondThumbVal, $secondThumb); + settings.onChange.call(element, value, module.thumbVal, module.secondThumbVal); + settings.onMove.call(element, value, module.thumbVal, module.secondThumbVal); + } else { + module.error(error.notrange); + } + }, + position: function(position, which) { + var thumbVal = module.determine.value(position); + switch (which) { + case 'second': + module.secondThumbVal = thumbVal; + module.update.position(thumbVal, $secondThumb); + break; + default: + module.thumbVal = thumbVal; + module.update.position(thumbVal, $thumb); + } + value = Math.abs(module.thumbVal - (module.secondThumbVal || 0)); + module.set.value(value); + } + }, + + update: { + value: function(newValue, callback) { + var + min = module.get.min(), + max = module.get.max() + ; + if (newValue <= min) { + newValue = min; + } else if(newValue >= max){ + newValue = max; + } + if(!module.is.range()) { + value = newValue; + module.thumbVal = value; + } else { + if(!$currThumb.hasClass('second')) { + module.thumbVal = newValue; + } else { + module.secondThumbVal = newValue; + } + value = Math.abs(module.thumbVal - module.secondThumbVal); + } + module.update.position(newValue); + module.debug('Setting slider value to ' + value); + if(typeof callback === 'function') { + callback(value, module.thumbVal, module.secondThumbVal); + } + }, + position: function(newValue, $element) { + var + newPos = module.handleNewValuePosition(newValue), + $targetThumb = $element != undefined ? $element : $currThumb, + thumbVal = module.thumbVal || module.get.min(), + secondThumbVal = module.secondThumbVal || module.get.min() + ; + if(module.is.range()) { + if(!$targetThumb.hasClass('second')) { + position = newPos; + thumbVal = newValue; + } else { + secondPos = newPos; + secondThumbVal = newValue; + } + } else { + position = newPos; + thumbVal = newValue; + } + var + trackPosValue, + thumbPosValue, + min = module.get.min(), + max = module.get.max(), + thumbPosPercent = 100 * (newValue - min) / (max - min), + trackStartPosPercent = 100 * (Math.min(thumbVal, secondThumbVal) - min) / (max - min), + trackEndPosPercent = 100 * (1 - (Math.max(thumbVal, secondThumbVal) - min) / (max - min)) + ; + if (module.is.vertical()) { + if (module.is.reversed()) { + thumbPosValue = {bottom: 'calc(' + thumbPosPercent + '% - ' + offset + 'px)', top: 'auto'}; + trackPosValue = {bottom: trackStartPosPercent + '%', top: trackEndPosPercent + '%'}; + } + else { + thumbPosValue = {top: 'calc(' + thumbPosPercent + '% - ' + offset + 'px)', bottom: 'auto'}; + trackPosValue = {top: trackStartPosPercent + '%', bottom: trackEndPosPercent + '%'}; + } + } else { + if (module.is.reversed()) { + thumbPosValue = {right: 'calc(' + thumbPosPercent + '% - ' + offset + 'px)', left: 'auto'}; + trackPosValue = {right: trackStartPosPercent + '%', left: trackEndPosPercent + '%'}; + } + else { + thumbPosValue = {left: 'calc(' + thumbPosPercent + '% - ' + offset + 'px)', right: 'auto'}; + trackPosValue = {left: trackStartPosPercent + '%', right: trackEndPosPercent + '%'}; + } + } + $targetThumb.css(thumbPosValue); + $trackFill.css(trackPosValue); + module.debug('Setting slider position to ' + newPos); + }, + labelPosition: function (ratio, $label) { + var + startMargin = module.get.trackStartMargin(), + endMargin = module.get.trackEndMargin(), + posDir = + module.is.vertical() + ? + module.is.reversed() ? 'bottom' : 'top' + : + module.is.reversed() ? 'right' : 'left', + startMarginMod = module.is.reversed() && !module.is.vertical() ? ' - ' : ' + ' + ; + var position = '(100% - ' + startMargin + ' - ' + endMargin + ') * ' + ratio; + $label.css(posDir, 'calc(' + position + startMarginMod + startMargin + ')'); + } + }, + + goto: { + max: function() { + module.set.value(module.get.max()); + }, + min: function() { + module.set.value(module.get.min()); + }, + }, + + read: { + metadata: function() { + var + data = { + thumbVal : $module.data(metadata.thumbVal), + secondThumbVal : $module.data(metadata.secondThumbVal) + } + ; + if(data.thumbVal) { + if(module.is.range() && data.secondThumbVal) { + module.debug('Current value set from metadata', data.thumbVal, data.secondThumbVal); + module.set.rangeValue(data.thumbVal, data.secondThumbVal); + } else { + module.debug('Current value set from metadata', data.thumbVal); + module.set.value(data.thumbVal); + } + } + }, + settings: function() { + if(settings.start !== false) { + if(module.is.range()) { + module.debug('Start position set from settings', settings.start, settings.end); + module.set.rangeValue(settings.start, settings.end); + } else { + module.debug('Start position set from settings', settings.start); + module.set.value(settings.start); + } + } + } + }, + + setting: function(name, value) { + module.debug('Changing setting', name, value); + if( $.isPlainObject(name) ) { + $.extend(true, settings, name); + } + else if(value !== undefined) { + if($.isPlainObject(settings[name])) { + $.extend(true, settings[name], value); + } + else { + settings[name] = value; + } + } + else { + return settings[name]; + } + }, + internal: function(name, value) { + if( $.isPlainObject(name) ) { + $.extend(true, module, name); + } + else if(value !== undefined) { + module[name] = value; + } + else { + return module[name]; + } + }, + debug: function() { + if(!settings.silent && settings.debug) { + if(settings.performance) { + module.performance.log(arguments); + } + else { + module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.debug.apply(console, arguments); + } + } + }, + verbose: function() { + if(!settings.silent && settings.verbose && settings.debug) { + if(settings.performance) { + module.performance.log(arguments); + } + else { + module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.verbose.apply(console, arguments); + } + } + }, + error: function() { + if(!settings.silent) { + module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); + module.error.apply(console, arguments); + } + }, + + performance: { + log: function(message) { + var + currentTime, + executionTime, + previousTime + ; + if(settings.performance) { + currentTime = new Date().getTime(); + previousTime = time || currentTime; + executionTime = currentTime - previousTime; + time = currentTime; + performance.push({ + 'Name' : message[0], + 'Arguments' : [].slice.call(message, 1) || '', + 'Element' : element, + 'Execution Time' : executionTime + }); + } + clearTimeout(module.performance.timer); + module.performance.timer = setTimeout(module.performance.display, 500); + }, + display: function() { + var + title = settings.name + ':', + totalTime = 0 + ; + time = false; + clearTimeout(module.performance.timer); + $.each(performance, function(index, data) { + totalTime += data['Execution Time']; + }); + title += ' ' + totalTime + 'ms'; + if(moduleSelector) { + title += ' \'' + moduleSelector + '\''; + } + if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { + console.groupCollapsed(title); + if(console.table) { + console.table(performance); + } + else { + $.each(performance, function(index, data) { + console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); + }); + } + console.groupEnd(); + } + performance = []; + } + }, + + invoke: function(query, passedArguments, context) { + var + object = instance, + maxDepth, + found, + response + ; + passedArguments = passedArguments || queryArguments; + context = element || context; + if(typeof query == 'string' && object !== undefined) { + query = query.split(/[\. ]/); + maxDepth = query.length - 1; + $.each(query, function(depth, value) { + var camelCaseValue = (depth != maxDepth) + ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) + : query + ; + if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { + object = object[camelCaseValue]; + } + else if( object[camelCaseValue] !== undefined ) { + found = object[camelCaseValue]; + return false; + } + else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { + object = object[value]; + } + else if( object[value] !== undefined ) { + found = object[value]; + return false; + } + else { + module.error(error.method, query); + return false; + } + }); + } + if ( $.isFunction( found ) ) { + response = found.apply(context, passedArguments); + } + else if(found !== undefined) { + response = found; + } + if($.isArray(returnedValue)) { + returnedValue.push(response); + } + else if(returnedValue !== undefined) { + returnedValue = [returnedValue, response]; + } + else if(response !== undefined) { + returnedValue = response; + } + return found; + } + }; + + if(methodInvoked) { + if(instance === undefined) { + module.initialize(); + } + module.invoke(query); + } + else { + if(instance !== undefined) { + instance.invoke('destroy'); + } + module.initialize(); + } + }) + ; + + return (returnedValue !== undefined) + ? returnedValue + : this + ; + +}; + +$.fn.slider.settings = { + + silent : false, + debug : false, + verbose : false, + performance : true, + + name : 'Slider', + namespace : 'slider', + + error : { + method : 'The method you called is not defined.', + notrange : 'This slider is not a range slider' + }, + + metadata: { + thumbVal : 'thumbVal', + secondThumbVal : 'secondThumbVal' + }, + + min : 0, + max : 20, + step : 1, + start : 0, + end : 20, + labelType : 'number', + showLabelTicks : false, + smooth : false, + + //the decimal place to round to if step is undefined + decimalPlaces : 2, + + // page up/down multiplier. How many more times the steps to take on page up/down press + pageMultiplier : 2, + + selector: { + + }, + + className : { + reversed : 'reversed', + disabled : 'disabled', + labeled : 'labeled', + ticked : 'ticked', + vertical : 'vertical', + range : 'range', + smooth : 'smooth' + }, + + keys : { + pageUp : 33, + pageDown : 34, + leftArrow : 37, + upArrow : 38, + rightArrow : 39, + downArrow : 40 + }, + + labelTypes : { + number : 'number', + letter : 'letter' + }, + + onChange : function(value, thumbVal, secondThumbVal){}, + onMove : function(value, thumbVal, secondThumbVal){}, +}; + + +})( jQuery, window, document ); diff --git a/src/definitions/modules/slider.less b/src/definitions/modules/slider.less new file mode 100644 index 0000000000..e4e82e2c4f --- /dev/null +++ b/src/definitions/modules/slider.less @@ -0,0 +1,455 @@ + /******************************* + Theme + *******************************/ + + @type : 'module'; + @element : 'slider'; + + @import (multiple) '../../theme.config'; + +.ui.slider:not(.vertical) { + width: 100%; + padding: @padding; +} + +.ui.slider { + position: relative; +} + +.ui.slider:focus { + outline: 0; +} + +.ui.slider .inner { + position: relative; + z-index: 2; +} + +.ui.slider:not(.vertical) .inner { + height: @height; +} + +.ui.slider .inner:hover { + cursor: @hoverPointer; +} + +.ui.slider .inner .track { + position: absolute; + border-radius: @trackBorderRadius; + background-color: @trackColor; +} + +.ui.slider:not(.vertical) .inner .track { + width: 100%; + height: @trackHeight; + top: @trackPositionTop; + left: 0; +} + +.ui.slider .inner .track-fill { + position: absolute; + border-radius: @trackFillBorderRadius; + background-color: @trackFillColor; +} + +.ui.slider:not(.vertical) .inner .track-fill { + height: @trackFillHeight; + top: @trackPositionTop; + left: 0; +} + +.ui.slider .inner .thumb { + position: absolute; + left: 0; + top: 0; + height: @thumbHeight; + width: @thumbHeight; + background: @thumbBackground; + border-radius: @thumbBorderRadius; + box-shadow: @thumbShadow; + transition: @thumbTransition; +} + +.ui.slider:not(.disabled) .inner .thumb:hover { + cursor: @thumbHoverPointer; + background: @thumbHoverBackground; +} + +.ui.slider:not(.disabled):focus .inner .thumb { + background: @thumbHoverBackground; +} + + +/******************************* + States +*******************************/ + + +/*-------------- + Disabled +---------------*/ + +.ui.disabled.slider { + opacity: @disabledOpactiy; +} + +.ui.disabled.slider .inner:hover { + cursor: auto; +} + +.ui.disabled.slider .inner .track-fill { + background: @disabledTrackFillColor; +} + +/*-------------- + Reversed +---------------*/ + +.ui.reversed.slider .inner .track-fill { + left: auto; + right: 0; +} + +.ui.reversed.slider .inner .thumb { + left: auto; + right: 0; +} + +.ui.labeled.reversed.slider > .labels .label { + transform: translate(-100%, -100%); +} + +/******************************* + Variations +*******************************/ + +/*-------------- + Vertical +---------------*/ + +.ui.vertical.slider { + height: 100%; + width: @height; + padding: @verticalPadding; +} + +.ui.vertical.slider .inner { + height: 100%; +} + +.ui.vertical.slider .inner .track { + height: 100%; + width: @trackHeight; + left: @trackPositionTop; + top: 0; +} + +.ui.vertical.slider .inner .track-fill { + width: @trackFillHeight; + left: @trackPositionTop; + top: 0; +} + +/* Vertical Reversed */ +.ui.vertical.reversed.slider .inner .thumb { + top: auto; + bottom: 0; +} + +.ui.vertical.reversed.slider .inner .track-fill { + top: auto; + bottom: 0; +} + +/*-------------- + Labeled +---------------*/ + +.ui.labeled.slider > .labels { + height: @labelHeight; + width: auto; + margin: 0; + padding: 0; + position: absolute; + top: 50%; + left: 0; + right: 0; +} + +.ui.labeled.slider:not(.vertical) > .labels { + transform: translateY(-50%); +} + +.ui.labeled.slider > .labels .label { + display: inline-flex; + position: absolute; + transform: translate(-50%, -100%); +} + +.ui.labeled.ticked.slider > .labels .label:after { + content: ' '; + height: @labelHeight; + width: @labelWidth; + background: @labelColor; + position: absolute; + top: 100%; + left: 50%; +} + +/* Vertical Labels */ + +.ui.labeled.vertical.slider > .labels { + width: @labelHeight; + height: auto; + left: 50%; + top: 0; + bottom: 0; + transform: translateX(-50%); +} + +.ui.labeled.vertical.slider > .labels .label { + transform: translate(-100%, -50%); +} + +.ui.labeled.vertical.slider > .labels .label:after { + width: @labelHeight; + height: @labelWidth; + left: 100%; + top: 50%; +} + +/* Vertical Reversed Labels */ +.ui.labeled.vertical.reversed.slider > .labels .label { + transform: translate(-100%, 50%); +} + +/*-------------- + Hover +---------------*/ + +.ui.hover.slider .inner .thumb { + opacity: @hoverVarOpacity; + transition: @hoverOpacityTransition; +} + +.ui.hover.slider:not(.disabled):hover .inner .thumb, .ui.hover.slider:not(.disabled):focus .inner .thumb { + opacity: @hoverVarHoverOpacity; +} + + + +/*-------------- + Inverted +---------------*/ + +.ui.inverted.slider .inner .track-fill { + background-color: @invertedTrackFillColor; +} + +.ui.inverted.slider .inner .track { + background-color: @transparentWhite; +} + +/*-------------- + Colors +---------------*/ + +.addColor(@color, @lightColor, @hoverColor, @lightHoverColor) { + @_color: "@{color}"; + @_lightColor: "@{lightColor}"; + @_hoverColor: "@{hoverColor}"; + @_lightHoverColor: "@{lightHoverColor}"; + + /* Standard */ + .ui.@{color}.slider .inner .track-fill { + background-color: @@_color; + } + .ui.@{color}.inverted.slider .inner .track-fill { + background-color: @@_lightColor; + } + + /* Basic */ + .ui.@{color}.slider.basic .inner .thumb { + background-color: @@_color; + } + .ui.@{color}.slider.basic .inner .thumb:hover, + .ui.@{color}.slider.basic:focus .inner .thumb { + background-color: @@_hoverColor; + } + + /* Basic Inverted */ + .ui.@{color}.inverted.slider.basic .inner .thumb { + background-color: @@_lightColor; + } + .ui.@{color}.inverted.slider.basic .inner .thumb:hover, + .ui.@{color}.inverted.slider.basic:focus .inner .thumb { + background-color: @@_lightHoverColor; + } + +} + +/*--- Red ---*/ +.addColor(~"red", ~"lightRed", ~"redHover", ~"lightRedHover"); + +/*--- Orange ---*/ +.addColor(~"orange", ~"lightOrange", ~"orangeHover", ~"lightOrangeHover"); + +/*--- Yellow ---*/ +.addColor(~"yellow", ~"lightYellow", ~"yellowHover", ~"lightYellowHover"); + +/*--- Olive ---*/ +.addColor(~"olive", ~"lightOlive", ~"oliveHover", ~"lightOliveHover"); + +/*--- Green ---*/ +.addColor(~"green", ~"lightGreen", ~"greenHover", ~"lightGreenHover"); + +/*--- Teal ---*/ +.addColor(~"teal", ~"lightTeal", ~"tealHover", ~"lightTealHover"); + +/*--- Blue ---*/ +.addColor(~"blue", ~"lightBlue", ~"blueHover", ~"lightBlueHover"); + +/*--- Violet ---*/ +.addColor(~"violet", ~"lightViolet", ~"violetHover", ~"lightVioletHover"); + +/*--- Purple ---*/ +.addColor(~"purple", ~"lightPurple", ~"purpleHover", ~"lightPurpleHover"); + +/*--- Pink ---*/ +.addColor(~"pink", ~"lightPink", ~"pinkHover", ~"lightPinkHover"); + +/*--- Brown ---*/ +.addColor(~"brown", ~"lightBrown", ~"brownHover", ~"lightBrownHover"); + +/*--- Grey ---*/ +.addColor(~"grey", ~"lightGrey", ~"greyHover", ~"lightGreyHover"); + +/*--- Black ---*/ +.addColor(~"black", ~"lightBlack", ~"blackHover", ~"lightBlackHover"); + +/*-------------- + Basic +---------------*/ + +/* Standard */ +.ui.slider.basic .inner .thumb { + background-color: @trackFillColor; +} +.ui.slider.basic .inner .thumb:hover, .ui.slider.basic:focus .inner .thumb { + background-color: @trackFillColorFocus; +} + +/*-------------- + Basic Inverted +---------------*/ + +/* Standard */ +.ui.inverted.slider.basic .inner .thumb { + background-color: @invertedTrackFillColor; +} +.ui.inverted.slider.basic .inner .thumb:hover, .ui.inverted.slider.basic:focus .inner .thumb { + background-color: @invertedTrackFillColorFocus; +} + + +/*-------------- + Sizing +---------------*/ + +/* Small */ +.ui.slider.small .inner .thumb { + height: @smallHeight; + width: @smallHeight; +} +.ui.slider.small:not(.vertical) .inner { + height: @smallHeight; +} +.ui.slider.small:not(.vertical) .inner .track, +.ui.slider.small:not(.vertical) .inner .track-fill { + height: @smallTrackHeight; + top: @trackPositionTopSmall; +} +.ui.small.labeled.slider:not(.vertical) > .labels, +.ui.small.labeled.slider:not(.vertical) > .labels .label:after { + height: @smallLabelHeight; +} + +/* Small Vertical */ +.ui.slider.small.vertical .inner { + width: @smallHeight; +} +.ui.slider.small.vertical .inner .track, +.ui.slider.small.vertical .inner .track-fill { + width: @smallTrackHeight; + left: @trackPositionTopSmall; +} +.ui.small.labeled.vertical.slider> .labels, +.ui.small.labeled.vertical.slider> .labels .label:after { + width: @smallLabelHeight; +} + +/* Large */ +.ui.slider.large .inner .thumb { + height: @largeHeight; + width: @largeHeight; +} +.ui.slider.large:not(.vertical) .inner { + height: @largeHeight; +} +.ui.slider.large:not(.vertical) .inner .track, +.ui.slider.large:not(.vertical) .inner .track-fill { + height: @largeTrackHeight; + top: @trackPositionTopLarge; +} +.ui.large.labeled.slider:not(.vertical) > .labels, +.ui.large.labeled.slider:not(.vertical) > .labels .label:after { + height: @largeLabelHeight; +} + +/* Large Vertical */ +.ui.slider.large.vertical .inner { + width: @largeHeight; +} +.ui.slider.large.vertical .inner .track, +.ui.slider.large.vertical .inner .track-fill { + width: @largeTrackHeight; + left: @trackPositionTopLarge; +} +.ui.large.labeled.vertical.slider> .labels, +.ui.large.labeled.vertical.slider> .labels .label:after { + width: @largeLabelHeight; +} + +/* Big */ +.ui.slider.big .inner .thumb { + height: @bigHeight; + width: @bigHeight; +} +.ui.slider.big:not(.vertical) .inner { + height: @bigHeight; +} +.ui.slider.big:not(.vertical) .inner .track, +.ui.slider.big:not(.vertical) .inner .track-fill { + height: @bigTrackHeight; + top: @trackPositionTopBig; +} +.ui.big.labeled.slider:not(.vertical) > .labels, +.ui.big.labeled.slider:not(.vertical) > .labels .label:after { + height: @bigLabelHeight; +} + +/* Big Vertical */ +.ui.slider.big.vertical .inner { + width: @bigHeight; +} +.ui.slider.big.vertical .inner .track, +.ui.slider.big.vertical .inner .track-fill { + width: @bigTrackHeight; + left: @trackPositionTopBig; +} +.ui.big.labeled.vertical.slider> .labels, +.ui.big.labeled.vertical.slider> .labels .label:after { + width: @bigLabelHeight; +} + +.loadUIOverrides(); diff --git a/src/semantic.less b/src/semantic.less index 155ef9446a..aebcde5bb4 100644 --- a/src/semantic.less +++ b/src/semantic.less @@ -59,7 +59,7 @@ & { @import "definitions/modules/nag"; } & { @import "definitions/modules/popup"; } & { @import "definitions/modules/progress"; } -& { @import "definitions/modules/range"; } +& { @import "definitions/modules/slider"; } & { @import "definitions/modules/rating"; } & { @import "definitions/modules/search"; } & { @import "definitions/modules/shape"; } diff --git a/src/theme.config.example b/src/theme.config.example index cebbc38a53..96c8bbeaaa 100644 --- a/src/theme.config.example +++ b/src/theme.config.example @@ -58,7 +58,7 @@ @nag : 'default'; @popup : 'default'; @progress : 'default'; -@range : 'default'; +@slider : 'default'; @rating : 'default'; @search : 'default'; @shape : 'default'; diff --git a/src/themes/default/modules/range.variables b/src/themes/default/modules/range.variables deleted file mode 100644 index c5979a64ab..0000000000 --- a/src/themes/default/modules/range.variables +++ /dev/null @@ -1,30 +0,0 @@ -/******************************* - Range -*******************************/ - -@barHeight: 20px; -@barWidth: 100%; - -@innerMargin: 0 10px 0 10px; - -@hoverCursor: pointer; - -@trackHeight: 4px; -@trackWidth: 100%; -@trackBorderRadius: @absoluteBorderRadius; -@trackColor: rgba(0, 0, 0, .05); -@trackFillColor: @black; - -@thumbHeight: 20px; -@thumbWidth: 20px; -@thumbBackground: #fff linear-gradient(transparent, rgba(0, 0, 0, 0.05)); -@thumbBorderRadius: 100%; -@thumbBoxShadow: 0 1px 2px 0 rgba(34,36,38,.15),0 0 0 1px rgba(34,36,38,.15) inset; - -/* Inverted */ -@invertedTrackColor: rgba(255,255,255,.08); -@invertedTrackFillColor: @lightBlack; - -/* Disabled */ -@disabledOpacity: .5; -@disabledTrackFillColor: @grey; diff --git a/src/themes/default/modules/range.overrides b/src/themes/default/modules/slider.overrides similarity index 72% rename from src/themes/default/modules/range.overrides rename to src/themes/default/modules/slider.overrides index 14fb0da124..e5b96d287f 100644 --- a/src/themes/default/modules/range.overrides +++ b/src/themes/default/modules/slider.overrides @@ -1,3 +1,3 @@ /******************************* - Theme Overrides + Slider Overrides *******************************/ diff --git a/src/themes/default/modules/slider.variables b/src/themes/default/modules/slider.variables new file mode 100644 index 0000000000..9b7b5ec702 --- /dev/null +++ b/src/themes/default/modules/slider.variables @@ -0,0 +1,80 @@ +/******************************* + Slider Variables +*******************************/ + +/*------------------- + Element +--------------------*/ + +@height : 1.5em; +@hoverPointer : auto; +@padding : 1em .5em; + +/* Track */ +@trackHeight : .4em; +@trackPositionTop : (@height / 2) - (@trackHeight / 2); +@background : #ccc; +@trackBorderRadius : 4px; +@trackColor : @transparentBlack; + +/* Track Fill */ +@trackFillHeight : @trackHeight; +@trackFillColor : @black; +@trackFillColorFocus : @blackHover; +@invertedTrackFillColor : @lightBlack; +@invertedTrackFillColorFocus : @lightBlackHover; +@trackFillBorderRadius : @trackBorderRadius; + +/* Thumb */ +@thumbHeight : @height; +@thumbBorderRadius : 100%; +@thumbBackground : @white @subtleGradient; +@thumbShadow : @subtleShadow, 0 0 0 1px @borderColor inset; +@thumbTransitionDuration : 0.3s; +@thumbTransition : background @thumbTransitionDuration @defaultEasing; + +/* Thumb Hover */ +@thumbHoverPointer : pointer; +@thumbHoverBackground : @whiteHover @subtleGradient; + +/*------------------- + States +--------------------*/ + +/* Disabled */ +@disabledOpactiy : .5; +@disabledTrackFillColor : @background; + +/*------------------- + Variations +--------------------*/ + +/* Vertical */ +@verticalPadding : .5em 1em; + +/* Labeled */ +@labelHeight : @height; +@labelWidth : 1px; +@labelColor : @background; + +/* Hover */ +@hoverVarOpacity : 0; +@hoverVarHoverOpacity : 1; +@hoverOpacityTransitionDuration : 0.2s; +@hoverOpacityTransition : opacity @hoverOpacityTransitionDuration linear; + +/* Sizing */ +@smallHeight : 1em; +@smallLabelHeight : @smallHeight; +@smallTrackHeight : 0.3em; +@trackPositionTopSmall : (@smallHeight / 2) - (@smallTrackHeight / 2); + +@largeHeight : 2em; +@largeLabelHeight : @largeHeight; +@largeTrackHeight : 0.5em; +@trackPositionTopLarge : (@largeHeight / 2) - (@largeTrackHeight / 2); + +@bigHeight : 2.5em; +@bigLabelHeight : @bigHeight; +@bigTrackHeight : 0.6em; +@trackPositionTopBig : (@bigHeight / 2) - (@bigTrackHeight / 2); diff --git a/tasks/config/admin/release.js b/tasks/config/admin/release.js index 2c2397a480..7750c8ecf7 100644 --- a/tasks/config/admin/release.js +++ b/tasks/config/admin/release.js @@ -94,7 +94,7 @@ module.exports = { 'popup', 'progress', 'rail', - 'range', + 'slider', 'rating', 'reset', 'reveal', diff --git a/tasks/config/defaults.js b/tasks/config/defaults.js index 57db781b67..c6c5f00e8d 100644 --- a/tasks/config/defaults.js +++ b/tasks/config/defaults.js @@ -92,7 +92,7 @@ module.exports = { 'nag', 'popup', 'progress', - 'range', + 'slider', 'rating', 'search', 'shape', diff --git a/tasks/config/project/install.js b/tasks/config/project/install.js index e5813f7cfb..c7875f4424 100644 --- a/tasks/config/project/install.js +++ b/tasks/config/project/install.js @@ -393,7 +393,7 @@ module.exports = { { name: "placeholder", checked: true }, { name: "popup", checked: true }, { name: "progress", checked: true }, - { name: "range", checked: true }, + { name: "slider", checked: true }, { name: "rating", checked: true }, { name: "search", checked: true }, { name: "shape", checked: true },