diff options
| author | Fuwn <[email protected]> | 2020-12-14 23:21:39 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2020-12-14 23:21:39 -0800 |
| commit | 823344c19094680e80e2b56449a243e183db8b06 (patch) | |
| tree | 92277700547ea671331828caa258ace7aaaa46d5 /semantic/src/definitions | |
| parent | repo: angular (diff) | |
| download | me-823344c19094680e80e2b56449a243e183db8b06.tar.xz me-823344c19094680e80e2b56449a243e183db8b06.zip | |
:star:
Diffstat (limited to 'semantic/src/definitions')
75 files changed, 55650 insertions, 0 deletions
diff --git a/semantic/src/definitions/behaviors/api.js b/semantic/src/definitions/behaviors/api.js new file mode 100644 index 0000000..845046b --- /dev/null +++ b/semantic/src/definitions/behaviors/api.js @@ -0,0 +1,1177 @@ +/*! + * # Fomantic-UI - API + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +'use strict'; + +$.isWindow = $.isWindow || function(obj) { + return obj != null && obj === obj.window; +}; + + window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.api = $.fn.api = function(parameters) { + + var + // use window context if none specified + $allModules = $.isFunction(this) + ? $(window) + : $(this), + moduleSelector = $allModules.selector || '', + time = new Date().getTime(), + performance = [], + + query = arguments[0], + methodInvoked = (typeof query == 'string'), + queryArguments = [].slice.call(arguments, 1), + + returnedValue + ; + + $allModules + .each(function() { + var + settings = ( $.isPlainObject(parameters) ) + ? $.extend(true, {}, $.fn.api.settings, parameters) + : $.extend({}, $.fn.api.settings), + + // internal aliases + namespace = settings.namespace, + metadata = settings.metadata, + selector = settings.selector, + error = settings.error, + className = settings.className, + + // define namespaces for modules + eventNamespace = '.' + namespace, + moduleNamespace = 'module-' + namespace, + + // element that creates request + $module = $(this), + $form = $module.closest(selector.form), + + // context used for state + $context = (settings.stateContext) + ? $(settings.stateContext) + : $module, + + // request details + ajaxSettings, + requestSettings, + url, + data, + requestStartTime, + + // standard module + element = this, + context = $context[0], + instance = $module.data(moduleNamespace), + module + ; + + module = { + + initialize: function() { + if(!methodInvoked) { + module.bind.events(); + } + module.instantiate(); + }, + + instantiate: function() { + module.verbose('Storing instance of module', module); + instance = module; + $module + .data(moduleNamespace, instance) + ; + }, + + destroy: function() { + module.verbose('Destroying previous module for', element); + $module + .removeData(moduleNamespace) + .off(eventNamespace) + ; + }, + + bind: { + events: function() { + var + triggerEvent = module.get.event() + ; + if( triggerEvent ) { + module.verbose('Attaching API events to element', triggerEvent); + $module + .on(triggerEvent + eventNamespace, module.event.trigger) + ; + } + else if(settings.on == 'now') { + module.debug('Querying API endpoint immediately'); + module.query(); + } + } + }, + + decode: { + json: function(response) { + if(response !== undefined && typeof response == 'string') { + try { + response = JSON.parse(response); + } + catch(e) { + // isnt json string + } + } + return response; + } + }, + + read: { + cachedResponse: function(url) { + var + response + ; + if(window.Storage === undefined) { + module.error(error.noStorage); + return; + } + response = sessionStorage.getItem(url); + module.debug('Using cached response', url, response); + response = module.decode.json(response); + return response; + } + }, + write: { + cachedResponse: function(url, response) { + if(response && response === '') { + module.debug('Response empty, not caching', response); + return; + } + if(window.Storage === undefined) { + module.error(error.noStorage); + return; + } + if( $.isPlainObject(response) ) { + response = JSON.stringify(response); + } + sessionStorage.setItem(url, response); + module.verbose('Storing cached response for url', url, response); + } + }, + + query: function() { + + if(module.is.disabled()) { + module.debug('Element is disabled API request aborted'); + return; + } + + if(module.is.loading()) { + if(settings.interruptRequests) { + module.debug('Interrupting previous request'); + module.abort(); + } + else { + module.debug('Cancelling request, previous request is still pending'); + return; + } + } + + // pass element metadata to url (value, text) + if(settings.defaultData) { + $.extend(true, settings.urlData, module.get.defaultData()); + } + + // Add form content + if(settings.serializeForm) { + settings.data = module.add.formData(settings.data); + } + + // call beforesend and get any settings changes + requestSettings = module.get.settings(); + + // check if before send cancelled request + if(requestSettings === false) { + module.cancelled = true; + module.error(error.beforeSend); + return; + } + else { + module.cancelled = false; + } + + // get url + url = module.get.templatedURL(); + + if(!url && !module.is.mocked()) { + module.error(error.missingURL); + return; + } + + // replace variables + url = module.add.urlData( url ); + // missing url parameters + if( !url && !module.is.mocked()) { + return; + } + + requestSettings.url = settings.base + url; + + // look for jQuery ajax parameters in settings + ajaxSettings = $.extend(true, {}, settings, { + type : settings.method || settings.type, + data : data, + url : settings.base + url, + beforeSend : settings.beforeXHR, + success : function() {}, + failure : function() {}, + complete : function() {} + }); + + module.debug('Querying URL', ajaxSettings.url); + module.verbose('Using AJAX settings', ajaxSettings); + if(settings.cache === 'local' && module.read.cachedResponse(url)) { + module.debug('Response returned from local cache'); + module.request = module.create.request(); + module.request.resolveWith(context, [ module.read.cachedResponse(url) ]); + return; + } + + if( !settings.throttle ) { + module.debug('Sending request', data, ajaxSettings.method); + module.send.request(); + } + else { + if(!settings.throttleFirstRequest && !module.timer) { + module.debug('Sending request', data, ajaxSettings.method); + module.send.request(); + module.timer = setTimeout(function(){}, settings.throttle); + } + else { + module.debug('Throttling request', settings.throttle); + clearTimeout(module.timer); + module.timer = setTimeout(function() { + if(module.timer) { + delete module.timer; + } + module.debug('Sending throttled request', data, ajaxSettings.method); + module.send.request(); + }, settings.throttle); + } + } + + }, + + should: { + removeError: function() { + return ( settings.hideError === true || (settings.hideError === 'auto' && !module.is.form()) ); + } + }, + + is: { + disabled: function() { + return ($module.filter(selector.disabled).length > 0); + }, + expectingJSON: function() { + return settings.dataType === 'json' || settings.dataType === 'jsonp'; + }, + form: function() { + return $module.is('form') || $context.is('form'); + }, + mocked: function() { + return (settings.mockResponse || settings.mockResponseAsync || settings.response || settings.responseAsync); + }, + input: function() { + return $module.is('input'); + }, + loading: function() { + return (module.request) + ? (module.request.state() == 'pending') + : false + ; + }, + abortedRequest: function(xhr) { + if(xhr && xhr.readyState !== undefined && xhr.readyState === 0) { + module.verbose('XHR request determined to be aborted'); + return true; + } + else { + module.verbose('XHR request was not aborted'); + return false; + } + }, + validResponse: function(response) { + if( (!module.is.expectingJSON()) || !$.isFunction(settings.successTest) ) { + module.verbose('Response is not JSON, skipping validation', settings.successTest, response); + return true; + } + module.debug('Checking JSON returned success', settings.successTest, response); + if( settings.successTest(response) ) { + module.debug('Response passed success test', response); + return true; + } + else { + module.debug('Response failed success test', response); + return false; + } + } + }, + + was: { + cancelled: function() { + return (module.cancelled || false); + }, + succesful: function() { + module.verbose('This behavior will be deleted due to typo. Use "was successful" instead.'); + return module.was.successful(); + }, + successful: function() { + return (module.request && module.request.state() == 'resolved'); + }, + failure: function() { + return (module.request && module.request.state() == 'rejected'); + }, + complete: function() { + return (module.request && (module.request.state() == 'resolved' || module.request.state() == 'rejected') ); + } + }, + + add: { + urlData: function(url, urlData) { + var + requiredVariables, + optionalVariables + ; + if(url) { + requiredVariables = url.match(settings.regExp.required); + optionalVariables = url.match(settings.regExp.optional); + urlData = urlData || settings.urlData; + if(requiredVariables) { + module.debug('Looking for required URL variables', requiredVariables); + $.each(requiredVariables, function(index, templatedString) { + var + // allow legacy {$var} style + variable = (templatedString.indexOf('$') !== -1) + ? templatedString.substr(2, templatedString.length - 3) + : templatedString.substr(1, templatedString.length - 2), + value = ($.isPlainObject(urlData) && urlData[variable] !== undefined) + ? urlData[variable] + : ($module.data(variable) !== undefined) + ? $module.data(variable) + : ($context.data(variable) !== undefined) + ? $context.data(variable) + : urlData[variable] + ; + // remove value + if(value === undefined) { + module.error(error.requiredParameter, variable, url); + url = false; + return false; + } + else { + module.verbose('Found required variable', variable, value); + value = (settings.encodeParameters) + ? module.get.urlEncodedValue(value) + : value + ; + url = url.replace(templatedString, value); + } + }); + } + if(optionalVariables) { + module.debug('Looking for optional URL variables', requiredVariables); + $.each(optionalVariables, function(index, templatedString) { + var + // allow legacy {/$var} style + variable = (templatedString.indexOf('$') !== -1) + ? templatedString.substr(3, templatedString.length - 4) + : templatedString.substr(2, templatedString.length - 3), + value = ($.isPlainObject(urlData) && urlData[variable] !== undefined) + ? urlData[variable] + : ($module.data(variable) !== undefined) + ? $module.data(variable) + : ($context.data(variable) !== undefined) + ? $context.data(variable) + : urlData[variable] + ; + // optional replacement + if(value !== undefined) { + module.verbose('Optional variable Found', variable, value); + url = url.replace(templatedString, value); + } + else { + module.verbose('Optional variable not found', variable); + // remove preceding slash if set + if(url.indexOf('/' + templatedString) !== -1) { + url = url.replace('/' + templatedString, ''); + } + else { + url = url.replace(templatedString, ''); + } + } + }); + } + } + return url; + }, + formData: function(data) { + var + canSerialize = ($.fn.serializeObject !== undefined), + formData = (canSerialize) + ? $form.serializeObject() + : $form.serialize(), + hasOtherData + ; + data = data || settings.data; + hasOtherData = $.isPlainObject(data); + + if(hasOtherData) { + if(canSerialize) { + module.debug('Extending existing data with form data', data, formData); + data = $.extend(true, {}, data, formData); + } + else { + module.error(error.missingSerialize); + module.debug('Cant extend data. Replacing data with form data', data, formData); + data = formData; + } + } + else { + module.debug('Adding form data', formData); + data = formData; + } + return data; + } + }, + + send: { + request: function() { + module.set.loading(); + module.request = module.create.request(); + if( module.is.mocked() ) { + module.mockedXHR = module.create.mockedXHR(); + } + else { + module.xhr = module.create.xhr(); + } + settings.onRequest.call(context, module.request, module.xhr); + } + }, + + event: { + trigger: function(event) { + module.query(); + if(event.type == 'submit' || event.type == 'click') { + event.preventDefault(); + } + }, + xhr: { + always: function() { + // nothing special + }, + done: function(response, textStatus, xhr) { + var + context = this, + elapsedTime = (new Date().getTime() - requestStartTime), + timeLeft = (settings.loadingDuration - elapsedTime), + translatedResponse = ( $.isFunction(settings.onResponse) ) + ? module.is.expectingJSON() && !settings.rawResponse + ? settings.onResponse.call(context, $.extend(true, {}, response)) + : settings.onResponse.call(context, response) + : false + ; + timeLeft = (timeLeft > 0) + ? timeLeft + : 0 + ; + if(translatedResponse) { + module.debug('Modified API response in onResponse callback', settings.onResponse, translatedResponse, response); + response = translatedResponse; + } + if(timeLeft > 0) { + module.debug('Response completed early delaying state change by', timeLeft); + } + setTimeout(function() { + if( module.is.validResponse(response) ) { + module.request.resolveWith(context, [response, xhr]); + } + else { + module.request.rejectWith(context, [xhr, 'invalid']); + } + }, timeLeft); + }, + fail: function(xhr, status, httpMessage) { + var + context = this, + elapsedTime = (new Date().getTime() - requestStartTime), + timeLeft = (settings.loadingDuration - elapsedTime) + ; + timeLeft = (timeLeft > 0) + ? timeLeft + : 0 + ; + if(timeLeft > 0) { + module.debug('Response completed early delaying state change by', timeLeft); + } + setTimeout(function() { + if( module.is.abortedRequest(xhr) ) { + module.request.rejectWith(context, [xhr, 'aborted', httpMessage]); + } + else { + module.request.rejectWith(context, [xhr, 'error', status, httpMessage]); + } + }, timeLeft); + } + }, + request: { + done: function(response, xhr) { + module.debug('Successful API Response', response); + if(settings.cache === 'local' && url) { + module.write.cachedResponse(url, response); + module.debug('Saving server response locally', module.cache); + } + settings.onSuccess.call(context, response, $module, xhr); + }, + complete: function(firstParameter, secondParameter) { + var + xhr, + response + ; + // have to guess callback parameters based on request success + if( module.was.successful() ) { + response = firstParameter; + xhr = secondParameter; + } + else { + xhr = firstParameter; + response = module.get.responseFromXHR(xhr); + } + module.remove.loading(); + settings.onComplete.call(context, response, $module, xhr); + }, + fail: function(xhr, status, httpMessage) { + var + // pull response from xhr if available + response = module.get.responseFromXHR(xhr), + errorMessage = module.get.errorFromRequest(response, status, httpMessage) + ; + if(status == 'aborted') { + module.debug('XHR Aborted (Most likely caused by page navigation or CORS Policy)', status, httpMessage); + settings.onAbort.call(context, status, $module, xhr); + return true; + } + else if(status == 'invalid') { + module.debug('JSON did not pass success test. A server-side error has most likely occurred', response); + } + else if(status == 'error') { + if(xhr !== undefined) { + module.debug('XHR produced a server error', status, httpMessage); + // make sure we have an error to display to console + if( (xhr.status < 200 || xhr.status >= 300) && httpMessage !== undefined && httpMessage !== '') { + module.error(error.statusMessage + httpMessage, ajaxSettings.url); + } + settings.onError.call(context, errorMessage, $module, xhr); + } + } + + if(settings.errorDuration && status !== 'aborted') { + module.debug('Adding error state'); + module.set.error(); + if( module.should.removeError() ) { + setTimeout(module.remove.error, settings.errorDuration); + } + } + module.debug('API Request failed', errorMessage, xhr); + settings.onFailure.call(context, response, $module, xhr); + } + } + }, + + create: { + + request: function() { + // api request promise + return $.Deferred() + .always(module.event.request.complete) + .done(module.event.request.done) + .fail(module.event.request.fail) + ; + }, + + mockedXHR: function () { + var + // xhr does not simulate these properties of xhr but must return them + textStatus = false, + status = false, + httpMessage = false, + responder = settings.mockResponse || settings.response, + asyncResponder = settings.mockResponseAsync || settings.responseAsync, + asyncCallback, + response, + mockedXHR + ; + + mockedXHR = $.Deferred() + .always(module.event.xhr.complete) + .done(module.event.xhr.done) + .fail(module.event.xhr.fail) + ; + + if(responder) { + if( $.isFunction(responder) ) { + module.debug('Using specified synchronous callback', responder); + response = responder.call(context, requestSettings); + } + else { + module.debug('Using settings specified response', responder); + response = responder; + } + // simulating response + mockedXHR.resolveWith(context, [ response, textStatus, { responseText: response }]); + } + else if( $.isFunction(asyncResponder) ) { + asyncCallback = function(response) { + module.debug('Async callback returned response', response); + + if(response) { + mockedXHR.resolveWith(context, [ response, textStatus, { responseText: response }]); + } + else { + mockedXHR.rejectWith(context, [{ responseText: response }, status, httpMessage]); + } + }; + module.debug('Using specified async response callback', asyncResponder); + asyncResponder.call(context, requestSettings, asyncCallback); + } + return mockedXHR; + }, + + xhr: function() { + var + xhr + ; + // ajax request promise + xhr = $.ajax(ajaxSettings) + .always(module.event.xhr.always) + .done(module.event.xhr.done) + .fail(module.event.xhr.fail) + ; + module.verbose('Created server request', xhr, ajaxSettings); + return xhr; + } + }, + + set: { + error: function() { + module.verbose('Adding error state to element', $context); + $context.addClass(className.error); + }, + loading: function() { + module.verbose('Adding loading state to element', $context); + $context.addClass(className.loading); + requestStartTime = new Date().getTime(); + } + }, + + remove: { + error: function() { + module.verbose('Removing error state from element', $context); + $context.removeClass(className.error); + }, + loading: function() { + module.verbose('Removing loading state from element', $context); + $context.removeClass(className.loading); + } + }, + + get: { + responseFromXHR: function(xhr) { + return $.isPlainObject(xhr) + ? (module.is.expectingJSON()) + ? module.decode.json(xhr.responseText) + : xhr.responseText + : false + ; + }, + errorFromRequest: function(response, status, httpMessage) { + return ($.isPlainObject(response) && response.error !== undefined) + ? response.error // use json error message + : (settings.error[status] !== undefined) // use server error message + ? settings.error[status] + : httpMessage + ; + }, + request: function() { + return module.request || false; + }, + xhr: function() { + return module.xhr || false; + }, + settings: function() { + var + runSettings + ; + runSettings = settings.beforeSend.call($module, settings); + if(runSettings) { + if(runSettings.success !== undefined) { + module.debug('Legacy success callback detected', runSettings); + module.error(error.legacyParameters, runSettings.success); + runSettings.onSuccess = runSettings.success; + } + if(runSettings.failure !== undefined) { + module.debug('Legacy failure callback detected', runSettings); + module.error(error.legacyParameters, runSettings.failure); + runSettings.onFailure = runSettings.failure; + } + if(runSettings.complete !== undefined) { + module.debug('Legacy complete callback detected', runSettings); + module.error(error.legacyParameters, runSettings.complete); + runSettings.onComplete = runSettings.complete; + } + } + if(runSettings === undefined) { + module.error(error.noReturnedValue); + } + if(runSettings === false) { + return runSettings; + } + return (runSettings !== undefined) + ? $.extend(true, {}, runSettings) + : $.extend(true, {}, settings) + ; + }, + urlEncodedValue: function(value) { + var + decodedValue = window.decodeURIComponent(value), + encodedValue = window.encodeURIComponent(value), + alreadyEncoded = (decodedValue !== value) + ; + if(alreadyEncoded) { + module.debug('URL value is already encoded, avoiding double encoding', value); + return value; + } + module.verbose('Encoding value using encodeURIComponent', value, encodedValue); + return encodedValue; + }, + defaultData: function() { + var + data = {} + ; + if( !$.isWindow(element) ) { + if( module.is.input() ) { + data.value = $module.val(); + } + else if( module.is.form() ) { + + } + else { + data.text = $module.text(); + } + } + return data; + }, + event: function() { + if( $.isWindow(element) || settings.on == 'now' ) { + module.debug('API called without element, no events attached'); + return false; + } + else if(settings.on == 'auto') { + if( $module.is('input') ) { + return (element.oninput !== undefined) + ? 'input' + : (element.onpropertychange !== undefined) + ? 'propertychange' + : 'keyup' + ; + } + else if( $module.is('form') ) { + return 'submit'; + } + else { + return 'click'; + } + } + else { + return settings.on; + } + }, + templatedURL: function(action) { + action = action || $module.data(metadata.action) || settings.action || false; + url = $module.data(metadata.url) || settings.url || false; + if(url) { + module.debug('Using specified url', url); + return url; + } + if(action) { + module.debug('Looking up url for action', action, settings.api); + if(settings.api[action] === undefined && !module.is.mocked()) { + module.error(error.missingAction, settings.action, settings.api); + return; + } + url = settings.api[action]; + } + else if( module.is.form() ) { + url = $module.attr('action') || $context.attr('action') || false; + module.debug('No url or action specified, defaulting to form action', url); + } + return url; + } + }, + + abort: function() { + var + xhr = module.get.xhr() + ; + if( xhr && xhr.state() !== 'resolved') { + module.debug('Cancelling API request'); + xhr.abort(); + } + }, + + // reset state + reset: function() { + module.remove.error(); + module.remove.loading(); + }, + + 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(Array.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 + ; +}; + +$.api.settings = { + + name : 'API', + namespace : 'api', + + debug : false, + verbose : false, + performance : true, + + // object containing all templates endpoints + api : {}, + + // whether to cache responses + cache : true, + + // whether new requests should abort previous requests + interruptRequests : true, + + // event binding + on : 'auto', + + // context for applying state classes + stateContext : false, + + // duration for loading state + loadingDuration : 0, + + // whether to hide errors after a period of time + hideError : 'auto', + + // duration for error state + errorDuration : 2000, + + // whether parameters should be encoded with encodeURIComponent + encodeParameters : true, + + // API action to use + action : false, + + // templated URL to use + url : false, + + // base URL to apply to all endpoints + base : '', + + // data that will + urlData : {}, + + // whether to add default data to url data + defaultData : true, + + // whether to serialize closest form + serializeForm : false, + + // how long to wait before request should occur + throttle : 0, + + // whether to throttle first request or only repeated + throttleFirstRequest : true, + + // standard ajax settings + method : 'get', + data : {}, + dataType : 'json', + + // mock response + mockResponse : false, + mockResponseAsync : false, + + // aliases for mock + response : false, + responseAsync : false, + +// whether onResponse should work with response value without force converting into an object + rawResponse : false, + + // callbacks before request + beforeSend : function(settings) { return settings; }, + beforeXHR : function(xhr) {}, + onRequest : function(promise, xhr) {}, + + // after request + onResponse : false, // function(response) { }, + + // response was successful, if JSON passed validation + onSuccess : function(response, $module) {}, + + // request finished without aborting + onComplete : function(response, $module) {}, + + // failed JSON success test + onFailure : function(response, $module) {}, + + // server error + onError : function(errorMessage, $module) {}, + + // request aborted + onAbort : function(errorMessage, $module) {}, + + successTest : false, + + // errors + error : { + beforeSend : 'The before send function has aborted the request', + error : 'There was an error with your request', + exitConditions : 'API Request Aborted. Exit conditions met', + JSONParse : 'JSON could not be parsed during error handling', + legacyParameters : 'You are using legacy API success callback names', + method : 'The method you called is not defined', + missingAction : 'API action used but no url was defined', + missingSerialize : 'jquery-serialize-object is required to add form data to an existing data object', + missingURL : 'No URL specified for api event', + noReturnedValue : 'The beforeSend callback must return a settings object, beforeSend ignored.', + noStorage : 'Caching responses locally requires session storage', + parseError : 'There was an error parsing your request', + requiredParameter : 'Missing a required URL parameter: ', + statusMessage : 'Server gave an error: ', + timeout : 'Your request timed out' + }, + + regExp : { + required : /\{\$*[A-z0-9]+\}/g, + optional : /\{\/\$*[A-z0-9]+\}/g, + }, + + className: { + loading : 'loading', + error : 'error' + }, + + selector: { + disabled : '.disabled', + form : 'form' + }, + + metadata: { + action : 'action', + url : 'url' + } +}; + + + +})( jQuery, window, document ); diff --git a/semantic/src/definitions/behaviors/form.js b/semantic/src/definitions/behaviors/form.js new file mode 100644 index 0000000..6fbb07e --- /dev/null +++ b/semantic/src/definitions/behaviors/form.js @@ -0,0 +1,2033 @@ +/*! + * # Fomantic-UI - Form Validation + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +'use strict'; + +$.isFunction = $.isFunction || function(obj) { + return typeof obj === "function" && typeof obj.nodeType !== "number"; +}; + +window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.fn.form = function(parameters) { + var + $allModules = $(this), + moduleSelector = $allModules.selector || '', + + time = new Date().getTime(), + performance = [], + + query = arguments[0], + legacyParameters = arguments[1], + methodInvoked = (typeof query == 'string'), + queryArguments = [].slice.call(arguments, 1), + returnedValue + ; + $allModules + .each(function() { + var + $module = $(this), + element = this, + + formErrors = [], + keyHeldDown = false, + + // set at run-time + $field, + $group, + $message, + $prompt, + $submit, + $clear, + $reset, + + settings, + validation, + + metadata, + selector, + className, + regExp, + error, + + namespace, + moduleNamespace, + eventNamespace, + + submitting = false, + dirty = false, + history = ['clean', 'clean'], + + instance, + module + ; + + module = { + + initialize: function() { + + // settings grabbed at run time + module.get.settings(); + if(methodInvoked) { + if(instance === undefined) { + module.instantiate(); + } + module.invoke(query); + } + else { + if(instance !== undefined) { + instance.invoke('destroy'); + } + module.verbose('Initializing form validation', $module, settings); + module.bindEvents(); + module.set.defaults(); + if (settings.autoCheckRequired) { + module.set.autoCheck(); + } + module.instantiate(); + } + }, + + instantiate: function() { + module.verbose('Storing instance of module', module); + instance = module; + $module + .data(moduleNamespace, module) + ; + }, + + destroy: function() { + module.verbose('Destroying previous module', instance); + module.removeEvents(); + $module + .removeData(moduleNamespace) + ; + }, + + refresh: function() { + module.verbose('Refreshing selector cache'); + $field = $module.find(selector.field); + $group = $module.find(selector.group); + $message = $module.find(selector.message); + $prompt = $module.find(selector.prompt); + + $submit = $module.find(selector.submit); + $clear = $module.find(selector.clear); + $reset = $module.find(selector.reset); + }, + + submit: function() { + module.verbose('Submitting form', $module); + submitting = true; + $module.submit(); + }, + + attachEvents: function(selector, action) { + action = action || 'submit'; + $(selector).on('click' + eventNamespace, function(event) { + module[action](); + event.preventDefault(); + }); + }, + + bindEvents: function() { + module.verbose('Attaching form events'); + $module + .on('submit' + eventNamespace, module.validate.form) + .on('blur' + eventNamespace, selector.field, module.event.field.blur) + .on('click' + eventNamespace, selector.submit, module.submit) + .on('click' + eventNamespace, selector.reset, module.reset) + .on('click' + eventNamespace, selector.clear, module.clear) + ; + if(settings.keyboardShortcuts) { + $module.on('keydown' + eventNamespace, selector.field, module.event.field.keydown); + } + $field.each(function(index, el) { + var + $input = $(el), + type = $input.prop('type'), + inputEvent = module.get.changeEvent(type, $input) + ; + $input.on(inputEvent + eventNamespace, module.event.field.change); + }); + + // Dirty events + if (settings.preventLeaving) { + $(window).on('beforeunload' + eventNamespace, module.event.beforeUnload); + } + + $field.on('change click keyup keydown blur', function(e) { + $(this).triggerHandler(e.type + ".dirty"); + }); + + $field.on('change.dirty click.dirty keyup.dirty keydown.dirty blur.dirty', module.determine.isDirty); + + $module.on('dirty' + eventNamespace, function(e) { + settings.onDirty.call(); + }); + + $module.on('clean' + eventNamespace, function(e) { + settings.onClean.call(); + }) + }, + + clear: function() { + $field.each(function (index, el) { + var + $field = $(el), + $element = $field.parent(), + $fieldGroup = $field.closest($group), + $prompt = $fieldGroup.find(selector.prompt), + $calendar = $field.closest(selector.uiCalendar), + defaultValue = $field.data(metadata.defaultValue) || '', + isCheckbox = $element.is(selector.uiCheckbox), + isDropdown = $element.is(selector.uiDropdown) && module.can.useElement('dropdown'), + isCalendar = ($calendar.length > 0 && module.can.useElement('calendar')), + isErrored = $fieldGroup.hasClass(className.error) + ; + if(isErrored) { + module.verbose('Resetting error on field', $fieldGroup); + $fieldGroup.removeClass(className.error); + $prompt.remove(); + } + if(isDropdown) { + module.verbose('Resetting dropdown value', $element, defaultValue); + $element.dropdown('clear', true); + } + else if(isCheckbox) { + $field.prop('checked', false); + } + else if (isCalendar) { + $calendar.calendar('clear'); + } + else { + module.verbose('Resetting field value', $field, defaultValue); + $field.val(''); + } + }); + module.remove.states(); + }, + + reset: function() { + $field.each(function (index, el) { + var + $field = $(el), + $element = $field.parent(), + $fieldGroup = $field.closest($group), + $calendar = $field.closest(selector.uiCalendar), + $prompt = $fieldGroup.find(selector.prompt), + defaultValue = $field.data(metadata.defaultValue), + isCheckbox = $element.is(selector.uiCheckbox), + isDropdown = $element.is(selector.uiDropdown) && module.can.useElement('dropdown'), + isCalendar = ($calendar.length > 0 && module.can.useElement('calendar')), + isErrored = $fieldGroup.hasClass(className.error) + ; + if(defaultValue === undefined) { + return; + } + if(isErrored) { + module.verbose('Resetting error on field', $fieldGroup); + $fieldGroup.removeClass(className.error); + $prompt.remove(); + } + if(isDropdown) { + module.verbose('Resetting dropdown value', $element, defaultValue); + $element.dropdown('restore defaults', true); + } + else if(isCheckbox) { + module.verbose('Resetting checkbox value', $element, defaultValue); + $field.prop('checked', defaultValue); + } + else if (isCalendar) { + $calendar.calendar('set date', defaultValue); + } + else { + module.verbose('Resetting field value', $field, defaultValue); + $field.val(defaultValue); + } + }); + module.remove.states(); + }, + + determine: { + isValid: function() { + var + allValid = true + ; + $.each(validation, function(fieldName, field) { + if( !( module.validate.field(field, fieldName, true) ) ) { + allValid = false; + } + }); + return allValid; + }, + isDirty: function(e) { + var formIsDirty = false; + + $field.each(function(index, el) { + var + $el = $(el), + isCheckbox = ($el.filter(selector.checkbox).length > 0), + isDirty + ; + + if (isCheckbox) { + isDirty = module.is.checkboxDirty($el); + } else { + isDirty = module.is.fieldDirty($el); + } + + $el.data(settings.metadata.isDirty, isDirty); + + formIsDirty |= isDirty; + }); + + if (formIsDirty) { + module.set.dirty(); + } else { + module.set.clean(); + } + + if (e && e.namespace === 'dirty') { + e.stopImmediatePropagation(); + e.preventDefault(); + } + } + }, + + is: { + bracketedRule: function(rule) { + return (rule.type && rule.type.match(settings.regExp.bracket)); + }, + shorthandFields: function(fields) { + var + fieldKeys = Object.keys(fields), + firstRule = fields[fieldKeys[0]] + ; + return module.is.shorthandRules(firstRule); + }, + // duck type rule test + shorthandRules: function(rules) { + return (typeof rules == 'string' || Array.isArray(rules)); + }, + empty: function($field) { + if(!$field || $field.length === 0) { + return true; + } + else if($field.is(selector.checkbox)) { + return !$field.is(':checked'); + } + else { + return module.is.blank($field); + } + }, + blank: function($field) { + return String($field.val()).trim() === ''; + }, + valid: function(field, showErrors) { + var + allValid = true + ; + if(field) { + module.verbose('Checking if field is valid', field); + return module.validate.field(validation[field], field, !!showErrors); + } + else { + module.verbose('Checking if form is valid'); + $.each(validation, function(fieldName, field) { + if( !module.is.valid(fieldName, showErrors) ) { + allValid = false; + } + }); + return allValid; + } + }, + dirty: function() { + return dirty; + }, + clean: function() { + return !dirty; + }, + fieldDirty: function($el) { + var initialValue = $el.data(metadata.defaultValue); + // Explicitly check for null/undefined here as value may be `false`, so ($el.data(dataInitialValue) || '') would not work + if (initialValue == null) { initialValue = ''; } + else if(Array.isArray(initialValue)) { + initialValue = initialValue.toString(); + } + var currentValue = $el.val(); + if (currentValue == null) { currentValue = ''; } + // multiple select values are returned as arrays which are never equal, so do string conversion first + else if(Array.isArray(currentValue)) { + currentValue = currentValue.toString(); + } + // Boolean values can be encoded as "true/false" or "True/False" depending on underlying frameworks so we need a case insensitive comparison + var boolRegex = /^(true|false)$/i; + var isBoolValue = boolRegex.test(initialValue) && boolRegex.test(currentValue); + if (isBoolValue) { + var regex = new RegExp("^" + initialValue + "$", "i"); + return !regex.test(currentValue); + } + + return currentValue !== initialValue; + }, + checkboxDirty: function($el) { + var initialValue = $el.data(metadata.defaultValue); + var currentValue = $el.is(":checked"); + + return initialValue !== currentValue; + }, + justDirty: function() { + return (history[0] === 'dirty'); + }, + justClean: function() { + return (history[0] === 'clean'); + } + }, + + removeEvents: function() { + $module.off(eventNamespace); + $field.off(eventNamespace); + $submit.off(eventNamespace); + $field.off(eventNamespace); + }, + + event: { + field: { + keydown: function(event) { + var + $field = $(this), + key = event.which, + isInput = $field.is(selector.input), + isCheckbox = $field.is(selector.checkbox), + isInDropdown = ($field.closest(selector.uiDropdown).length > 0), + keyCode = { + enter : 13, + escape : 27 + } + ; + if( key == keyCode.escape) { + module.verbose('Escape key pressed blurring field'); + $field + .blur() + ; + } + if(!event.ctrlKey && key == keyCode.enter && isInput && !isInDropdown && !isCheckbox) { + if(!keyHeldDown) { + $field.one('keyup' + eventNamespace, module.event.field.keyup); + module.submit(); + module.debug('Enter pressed on input submitting form'); + } + keyHeldDown = true; + } + }, + keyup: function() { + keyHeldDown = false; + }, + blur: function(event) { + var + $field = $(this), + $fieldGroup = $field.closest($group), + validationRules = module.get.validation($field) + ; + if( $fieldGroup.hasClass(className.error) ) { + module.debug('Revalidating field', $field, validationRules); + if(validationRules) { + module.validate.field( validationRules ); + } + } + else if(settings.on == 'blur') { + if(validationRules) { + module.validate.field( validationRules ); + } + } + }, + change: function(event) { + var + $field = $(this), + $fieldGroup = $field.closest($group), + validationRules = module.get.validation($field) + ; + if(validationRules && (settings.on == 'change' || ( $fieldGroup.hasClass(className.error) && settings.revalidate) )) { + clearTimeout(module.timer); + module.timer = setTimeout(function() { + module.debug('Revalidating field', $field, module.get.validation($field)); + module.validate.field( validationRules ); + if(!settings.inline) { + module.validate.form(false,true); + } + }, settings.delay); + } + } + }, + beforeUnload: function(event) { + if (module.is.dirty() && !submitting) { + var event = event || window.event; + + // For modern browsers + if (event) { + event.returnValue = settings.text.leavingMessage; + } + + // For olders... + return settings.text.leavingMessage; + } + } + + }, + + get: { + ancillaryValue: function(rule) { + if(!rule.type || (!rule.value && !module.is.bracketedRule(rule))) { + return false; + } + return (rule.value !== undefined) + ? rule.value + : rule.type.match(settings.regExp.bracket)[1] + '' + ; + }, + ruleName: function(rule) { + if( module.is.bracketedRule(rule) ) { + return rule.type.replace(rule.type.match(settings.regExp.bracket)[0], ''); + } + return rule.type; + }, + changeEvent: function(type, $input) { + if(type == 'checkbox' || type == 'radio' || type == 'hidden' || $input.is('select')) { + return 'change'; + } + else { + return module.get.inputEvent(); + } + }, + inputEvent: function() { + return (document.createElement('input').oninput !== undefined) + ? 'input' + : (document.createElement('input').onpropertychange !== undefined) + ? 'propertychange' + : 'keyup' + ; + }, + fieldsFromShorthand: function(fields) { + var + fullFields = {} + ; + $.each(fields, function(name, rules) { + if(typeof rules == 'string') { + rules = [rules]; + } + fullFields[name] = { + rules: [] + }; + $.each(rules, function(index, rule) { + fullFields[name].rules.push({ type: rule }); + }); + }); + return fullFields; + }, + prompt: function(rule, field) { + var + ruleName = module.get.ruleName(rule), + ancillary = module.get.ancillaryValue(rule), + $field = module.get.field(field.identifier), + value = $field.val(), + prompt = $.isFunction(rule.prompt) + ? rule.prompt(value) + : rule.prompt || settings.prompt[ruleName] || settings.text.unspecifiedRule, + requiresValue = (prompt.search('{value}') !== -1), + requiresName = (prompt.search('{name}') !== -1), + $label, + name + ; + if(requiresValue) { + prompt = prompt.replace(/\{value\}/g, $field.val()); + } + if(requiresName) { + $label = $field.closest(selector.group).find('label').eq(0); + name = ($label.length == 1) + ? $label.text() + : $field.prop('placeholder') || settings.text.unspecifiedField + ; + prompt = prompt.replace(/\{name\}/g, name); + } + prompt = prompt.replace(/\{identifier\}/g, field.identifier); + prompt = prompt.replace(/\{ruleValue\}/g, ancillary); + if(!rule.prompt) { + module.verbose('Using default validation prompt for type', prompt, ruleName); + } + return prompt; + }, + settings: function() { + if($.isPlainObject(parameters)) { + var + keys = Object.keys(parameters), + isLegacySettings = (keys.length > 0) + ? (parameters[keys[0]].identifier !== undefined && parameters[keys[0]].rules !== undefined) + : false + ; + if(isLegacySettings) { + // 1.x (ducktyped) + settings = $.extend(true, {}, $.fn.form.settings, legacyParameters); + validation = $.extend({}, $.fn.form.settings.defaults, parameters); + module.error(settings.error.oldSyntax, element); + module.verbose('Extending settings from legacy parameters', validation, settings); + } + else { + // 2.x + if(parameters.fields && module.is.shorthandFields(parameters.fields)) { + parameters.fields = module.get.fieldsFromShorthand(parameters.fields); + } + settings = $.extend(true, {}, $.fn.form.settings, parameters); + validation = $.extend({}, $.fn.form.settings.defaults, settings.fields); + module.verbose('Extending settings', validation, settings); + } + } + else { + settings = $.fn.form.settings; + validation = $.fn.form.settings.defaults; + module.verbose('Using default form validation', validation, settings); + } + + // shorthand + namespace = settings.namespace; + metadata = settings.metadata; + selector = settings.selector; + className = settings.className; + regExp = settings.regExp; + error = settings.error; + moduleNamespace = 'module-' + namespace; + eventNamespace = '.' + namespace; + + // grab instance + instance = $module.data(moduleNamespace); + + // refresh selector cache + module.refresh(); + }, + field: function(identifier) { + module.verbose('Finding field with identifier', identifier); + identifier = module.escape.string(identifier); + var t; + if((t=$field.filter('#' + identifier)).length > 0 ) { + return t; + } + if((t=$field.filter('[name="' + identifier +'"]')).length > 0 ) { + return t; + } + if((t=$field.filter('[name="' + identifier +'[]"]')).length > 0 ) { + return t; + } + if((t=$field.filter('[data-' + metadata.validate + '="'+ identifier +'"]')).length > 0 ) { + return t; + } + return $('<input/>'); + }, + fields: function(fields) { + var + $fields = $() + ; + $.each(fields, function(index, name) { + $fields = $fields.add( module.get.field(name) ); + }); + return $fields; + }, + validation: function($field) { + var + fieldValidation, + identifier + ; + if(!validation) { + return false; + } + $.each(validation, function(fieldName, field) { + identifier = field.identifier || fieldName; + $.each(module.get.field(identifier), function(index, groupField) { + if(groupField == $field[0]) { + field.identifier = identifier; + fieldValidation = field; + return false; + } + }); + }); + return fieldValidation || false; + }, + value: function (field) { + var + fields = [], + results + ; + fields.push(field); + results = module.get.values.call(element, fields); + return results[field]; + }, + values: function (fields) { + var + $fields = Array.isArray(fields) + ? module.get.fields(fields) + : $field, + values = {} + ; + $fields.each(function(index, field) { + var + $field = $(field), + $calendar = $field.closest(selector.uiCalendar), + name = $field.prop('name'), + value = $field.val(), + isCheckbox = $field.is(selector.checkbox), + isRadio = $field.is(selector.radio), + isMultiple = (name.indexOf('[]') !== -1), + isCalendar = ($calendar.length > 0 && module.can.useElement('calendar')), + isChecked = (isCheckbox) + ? $field.is(':checked') + : false + ; + if(name) { + if(isMultiple) { + name = name.replace('[]', ''); + if(!values[name]) { + values[name] = []; + } + if(isCheckbox) { + if(isChecked) { + values[name].push(value || true); + } + else { + values[name].push(false); + } + } + else { + values[name].push(value); + } + } + else { + if(isRadio) { + if(values[name] === undefined || values[name] === false) { + values[name] = (isChecked) + ? value || true + : false + ; + } + } + else if(isCheckbox) { + if(isChecked) { + values[name] = value || true; + } + else { + values[name] = false; + } + } + else if(isCalendar) { + var date = $calendar.calendar('get date'); + + if (date !== null) { + if (settings.dateHandling == 'date') { + values[name] = date; + } else if(settings.dateHandling == 'input') { + values[name] = $calendar.calendar('get input date') + } else if (settings.dateHandling == 'formatter') { + var type = $calendar.calendar('setting', 'type'); + + switch(type) { + case 'date': + values[name] = settings.formatter.date(date); + break; + + case 'datetime': + values[name] = settings.formatter.datetime(date); + break; + + case 'time': + values[name] = settings.formatter.time(date); + break; + + case 'month': + values[name] = settings.formatter.month(date); + break; + + case 'year': + values[name] = settings.formatter.year(date); + break; + + default: + module.debug('Wrong calendar mode', $calendar, type); + values[name] = ''; + } + } + } else { + values[name] = ''; + } + } else { + values[name] = value; + } + } + } + }); + return values; + }, + dirtyFields: function() { + return $field.filter(function(index, e) { + return $(e).data(metadata.isDirty); + }); + } + }, + + has: { + + field: function(identifier) { + module.verbose('Checking for existence of a field with identifier', identifier); + identifier = module.escape.string(identifier); + if(typeof identifier !== 'string') { + module.error(error.identifier, identifier); + } + if($field.filter('#' + identifier).length > 0 ) { + return true; + } + else if( $field.filter('[name="' + identifier +'"]').length > 0 ) { + return true; + } + else if( $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]').length > 0 ) { + return true; + } + return false; + } + + }, + + can: { + useElement: function(element){ + if ($.fn[element] !== undefined) { + return true; + } + module.error(error.noElement.replace('{element}',element)); + return false; + } + }, + + escape: { + string: function(text) { + text = String(text); + return text.replace(regExp.escape, '\\$&'); + } + }, + + add: { + // alias + rule: function(name, rules) { + module.add.field(name, rules); + }, + field: function(name, rules) { + // Validation should have at least a standard format + if(validation[name] === undefined || validation[name].rules === undefined) { + validation[name] = { + rules: [] + }; + } + var + newValidation = { + rules: [] + } + ; + if(module.is.shorthandRules(rules)) { + rules = Array.isArray(rules) + ? rules + : [rules] + ; + $.each(rules, function(_index, rule) { + newValidation.rules.push({ type: rule }); + }); + } + else { + newValidation.rules = rules.rules; + } + // For each new rule, check if there's not already one with the same type + $.each(newValidation.rules, function (_index, rule) { + if ($.grep(validation[name].rules, function(item){ return item.type == rule.type; }).length == 0) { + validation[name].rules.push(rule); + } + }); + module.debug('Adding rules', newValidation.rules, validation); + }, + fields: function(fields) { + var + newValidation + ; + if(fields && module.is.shorthandFields(fields)) { + newValidation = module.get.fieldsFromShorthand(fields); + } + else { + newValidation = fields; + } + validation = $.extend({}, validation, newValidation); + }, + prompt: function(identifier, errors, internal) { + var + $field = module.get.field(identifier), + $fieldGroup = $field.closest($group), + $prompt = $fieldGroup.children(selector.prompt), + promptExists = ($prompt.length !== 0) + ; + errors = (typeof errors == 'string') + ? [errors] + : errors + ; + module.verbose('Adding field error state', identifier); + if(!internal) { + $fieldGroup + .addClass(className.error) + ; + } + if(settings.inline) { + if(!promptExists) { + $prompt = settings.templates.prompt(errors, className.label); + $prompt + .appendTo($fieldGroup) + ; + } + $prompt + .html(errors[0]) + ; + if(!promptExists) { + if(settings.transition && module.can.useElement('transition') && $module.transition('is supported')) { + module.verbose('Displaying error with css transition', settings.transition); + $prompt.transition(settings.transition + ' in', settings.duration); + } + else { + module.verbose('Displaying error with fallback javascript animation'); + $prompt + .fadeIn(settings.duration) + ; + } + } + else { + module.verbose('Inline errors are disabled, no inline error added', identifier); + } + } + }, + errors: function(errors) { + module.debug('Adding form error messages', errors); + module.set.error(); + $message + .html( settings.templates.error(errors) ) + ; + } + }, + + remove: { + errors: function() { + module.debug('Removing form error messages'); + $message.empty(); + }, + states: function() { + $module.removeClass(className.error).removeClass(className.success); + if(!settings.inline) { + module.remove.errors(); + } + module.determine.isDirty(); + }, + rule: function(field, rule) { + var + rules = Array.isArray(rule) + ? rule + : [rule] + ; + if(validation[field] === undefined || !Array.isArray(validation[field].rules)) { + return; + } + if(rule === undefined) { + module.debug('Removed all rules'); + validation[field].rules = []; + return; + } + $.each(validation[field].rules, function(index, rule) { + if(rule && rules.indexOf(rule.type) !== -1) { + module.debug('Removed rule', rule.type); + validation[field].rules.splice(index, 1); + } + }); + }, + field: function(field) { + var + fields = Array.isArray(field) + ? field + : [field] + ; + $.each(fields, function(index, field) { + module.remove.rule(field); + }); + }, + // alias + rules: function(field, rules) { + if(Array.isArray(field)) { + $.each(field, function(index, field) { + module.remove.rule(field, rules); + }); + } + else { + module.remove.rule(field, rules); + } + }, + fields: function(fields) { + module.remove.field(fields); + }, + prompt: function(identifier) { + var + $field = module.get.field(identifier), + $fieldGroup = $field.closest($group), + $prompt = $fieldGroup.children(selector.prompt) + ; + $fieldGroup + .removeClass(className.error) + ; + if(settings.inline && $prompt.is(':visible')) { + module.verbose('Removing prompt for field', identifier); + if(settings.transition && module.can.useElement('transition') && $module.transition('is supported')) { + $prompt.transition(settings.transition + ' out', settings.duration, function() { + $prompt.remove(); + }); + } + else { + $prompt + .fadeOut(settings.duration, function(){ + $prompt.remove(); + }) + ; + } + } + } + }, + + set: { + success: function() { + $module + .removeClass(className.error) + .addClass(className.success) + ; + }, + defaults: function () { + $field.each(function (index, el) { + var + $el = $(el), + $parent = $el.parent(), + isCheckbox = ($el.filter(selector.checkbox).length > 0), + isDropdown = $parent.is(selector.uiDropdown) && module.can.useElement('dropdown'), + $calendar = $el.closest(selector.uiCalendar), + isCalendar = ($calendar.length > 0 && module.can.useElement('calendar')), + value = (isCheckbox) + ? $el.is(':checked') + : $el.val() + ; + if (isDropdown) { + $parent.dropdown('save defaults'); + } + else if (isCalendar) { + $calendar.calendar('refresh'); + } + $el.data(metadata.defaultValue, value); + $el.data(metadata.isDirty, false); + }); + }, + error: function() { + $module + .removeClass(className.success) + .addClass(className.error) + ; + }, + value: function (field, value) { + var + fields = {} + ; + fields[field] = value; + return module.set.values.call(element, fields); + }, + values: function (fields) { + if($.isEmptyObject(fields)) { + return; + } + $.each(fields, function(key, value) { + var + $field = module.get.field(key), + $element = $field.parent(), + $calendar = $field.closest(selector.uiCalendar), + isMultiple = Array.isArray(value), + isCheckbox = $element.is(selector.uiCheckbox) && module.can.useElement('checkbox'), + isDropdown = $element.is(selector.uiDropdown) && module.can.useElement('dropdown'), + isRadio = ($field.is(selector.radio) && isCheckbox), + isCalendar = ($calendar.length > 0 && module.can.useElement('calendar')), + fieldExists = ($field.length > 0), + $multipleField + ; + if(fieldExists) { + if(isMultiple && isCheckbox) { + module.verbose('Selecting multiple', value, $field); + $element.checkbox('uncheck'); + $.each(value, function(index, value) { + $multipleField = $field.filter('[value="' + value + '"]'); + $element = $multipleField.parent(); + if($multipleField.length > 0) { + $element.checkbox('check'); + } + }); + } + else if(isRadio) { + module.verbose('Selecting radio value', value, $field); + $field.filter('[value="' + value + '"]') + .parent(selector.uiCheckbox) + .checkbox('check') + ; + } + else if(isCheckbox) { + module.verbose('Setting checkbox value', value, $element); + if(value === true || value === 1) { + $element.checkbox('check'); + } + else { + $element.checkbox('uncheck'); + } + } + else if(isDropdown) { + module.verbose('Setting dropdown value', value, $element); + $element.dropdown('set selected', value); + } + else if (isCalendar) { + $calendar.calendar('set date',value); + } + else { + module.verbose('Setting field value', value, $field); + $field.val(value); + } + } + }); + }, + dirty: function() { + module.verbose('Setting state dirty'); + dirty = true; + history[0] = history[1]; + history[1] = 'dirty'; + + if (module.is.justClean()) { + $module.trigger('dirty'); + } + }, + clean: function() { + module.verbose('Setting state clean'); + dirty = false; + history[0] = history[1]; + history[1] = 'clean'; + + if (module.is.justDirty()) { + $module.trigger('clean'); + } + }, + asClean: function() { + module.set.defaults(); + module.set.clean(); + }, + asDirty: function() { + module.set.defaults(); + module.set.dirty(); + }, + autoCheck: function() { + module.debug('Enabling auto check on required fields'); + $field.each(function (_index, el) { + var + $el = $(el), + $elGroup = $(el).closest($group), + isCheckbox = ($el.filter(selector.checkbox).length > 0), + isRequired = $el.prop('required') || $elGroup.hasClass(className.required) || $elGroup.parent().hasClass(className.required), + isDisabled = $el.is(':disabled') || $elGroup.hasClass(className.disabled) || $elGroup.parent().hasClass(className.disabled), + validation = module.get.validation($el), + hasEmptyRule = validation + ? $.grep(validation.rules, function(rule) { return rule.type == "empty" }) !== 0 + : false, + identifier = validation.identifier || $el.attr('id') || $el.attr('name') || $el.data(metadata.validate) + ; + if (isRequired && !isDisabled && !hasEmptyRule && identifier !== undefined) { + if (isCheckbox) { + module.verbose("Adding 'checked' rule on field", identifier); + module.add.rule(identifier, "checked"); + } else { + module.verbose("Adding 'empty' rule on field", identifier); + module.add.rule(identifier, "empty"); + } + } + }); + } + }, + + validate: { + + form: function(event, ignoreCallbacks) { + var values = module.get.values(); + + // input keydown event will fire submit repeatedly by browser default + if(keyHeldDown) { + return false; + } + + // reset errors + formErrors = []; + if( module.determine.isValid() ) { + module.debug('Form has no validation errors, submitting'); + module.set.success(); + if(!settings.inline) { + module.remove.errors(); + } + if(ignoreCallbacks !== true) { + return settings.onSuccess.call(element, event, values); + } + } + else { + module.debug('Form has errors'); + submitting = false; + module.set.error(); + if(!settings.inline) { + module.add.errors(formErrors); + } + // prevent ajax submit + if(event && $module.data('moduleApi') !== undefined) { + event.stopImmediatePropagation(); + } + if(ignoreCallbacks !== true) { + return settings.onFailure.call(element, formErrors, values); + } + } + }, + + // takes a validation object and returns whether field passes validation + field: function(field, fieldName, showErrors) { + showErrors = (showErrors !== undefined) + ? showErrors + : true + ; + if(typeof field == 'string') { + module.verbose('Validating field', field); + fieldName = field; + field = validation[field]; + } + var + identifier = field.identifier || fieldName, + $field = module.get.field(identifier), + $dependsField = (field.depends) + ? module.get.field(field.depends) + : false, + fieldValid = true, + fieldErrors = [] + ; + if(!field.identifier) { + module.debug('Using field name as identifier', identifier); + field.identifier = identifier; + } + var isDisabled = !$field.filter(':not(:disabled)').length; + if(isDisabled) { + module.debug('Field is disabled. Skipping', identifier); + } + else if(field.optional && module.is.blank($field)){ + module.debug('Field is optional and blank. Skipping', identifier); + } + else if(field.depends && module.is.empty($dependsField)) { + module.debug('Field depends on another value that is not present or empty. Skipping', $dependsField); + } + else if(field.rules !== undefined) { + if(showErrors) { + $field.closest($group).removeClass(className.error); + } + $.each(field.rules, function(index, rule) { + if( module.has.field(identifier)) { + var invalidFields = module.validate.rule(field, rule,true) || []; + if (invalidFields.length>0){ + module.debug('Field is invalid', identifier, rule.type); + fieldErrors.push(module.get.prompt(rule, field)); + fieldValid = false; + if(showErrors){ + $(invalidFields).closest($group).addClass(className.error); + } + } + } + }); + } + if(fieldValid) { + if(showErrors) { + module.remove.prompt(identifier, fieldErrors); + settings.onValid.call($field); + } + } + else { + if(showErrors) { + formErrors = formErrors.concat(fieldErrors); + module.add.prompt(identifier, fieldErrors, true); + settings.onInvalid.call($field, fieldErrors); + } + return false; + } + return true; + }, + + // takes validation rule and returns whether field passes rule + rule: function(field, rule, internal) { + var + $field = module.get.field(field.identifier), + ancillary = module.get.ancillaryValue(rule), + ruleName = module.get.ruleName(rule), + ruleFunction = settings.rules[ruleName], + invalidFields = [], + isCheckbox = $field.is(selector.checkbox), + isValid = function(field){ + var value = (isCheckbox ? $(field).filter(':checked').val() : $(field).val()); + // cast to string avoiding encoding special values + value = (value === undefined || value === '' || value === null) + ? '' + : (settings.shouldTrim) ? String(value + '').trim() : String(value + '') + ; + return ruleFunction.call(field, value, ancillary, $module); + } + ; + if( !$.isFunction(ruleFunction) ) { + module.error(error.noRule, ruleName); + return; + } + if(isCheckbox) { + if (!isValid($field)) { + invalidFields = $field; + } + } else { + $.each($field, function (index, field) { + if (!isValid(field)) { + invalidFields.push(field); + } + }); + } + return internal ? invalidFields : !(invalidFields.length>0); + } + }, + + setting: function(name, value) { + if( $.isPlainObject(name) ) { + $.extend(true, settings, name); + } + else if(value !== undefined) { + 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($allModules.length > 1) { + title += ' ' + '(' + $allModules.length + ')'; + } + 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 { + return false; + } + }); + } + if( $.isFunction( found ) ) { + response = found.apply(context, passedArguments); + } + else if(found !== undefined) { + response = found; + } + if(Array.isArray(returnedValue)) { + returnedValue.push(response); + } + else if(returnedValue !== undefined) { + returnedValue = [returnedValue, response]; + } + else if(response !== undefined) { + returnedValue = response; + } + return found; + } + }; + module.initialize(); + }) + ; + + return (returnedValue !== undefined) + ? returnedValue + : this + ; +}; + +$.fn.form.settings = { + + name : 'Form', + namespace : 'form', + + debug : false, + verbose : false, + performance : true, + + fields : false, + + keyboardShortcuts : true, + on : 'submit', + inline : false, + + delay : 200, + revalidate : true, + shouldTrim : true, + + transition : 'scale', + duration : 200, + + autoCheckRequired : false, + preventLeaving : false, + dateHandling : 'date', // 'date', 'input', 'formatter' + + onValid : function() {}, + onInvalid : function() {}, + onSuccess : function() { return true; }, + onFailure : function() { return false; }, + onDirty : function() {}, + onClean : function() {}, + + metadata : { + defaultValue : 'default', + validate : 'validate', + isDirty : 'isDirty' + }, + + regExp: { + htmlID : /^[a-zA-Z][\w:.-]*$/g, + bracket : /\[(.*)\]/i, + decimal : /^\d+\.?\d*$/, + email : /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i, + escape : /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|:,=@]/g, + flags : /^\/(.*)\/(.*)?/, + integer : /^\-?\d+$/, + number : /^\-?\d*(\.\d+)?$/, + url : /(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/i + }, + + text: { + unspecifiedRule : 'Please enter a valid value', + unspecifiedField : 'This field', + leavingMessage : 'There are unsaved changes on this page which will be discarded if you continue.' + }, + + prompt: { + empty : '{name} must have a value', + checked : '{name} must be checked', + email : '{name} must be a valid e-mail', + url : '{name} must be a valid url', + regExp : '{name} is not formatted correctly', + integer : '{name} must be an integer', + decimal : '{name} must be a decimal number', + number : '{name} must be set to a number', + is : '{name} must be "{ruleValue}"', + isExactly : '{name} must be exactly "{ruleValue}"', + not : '{name} cannot be set to "{ruleValue}"', + notExactly : '{name} cannot be set to exactly "{ruleValue}"', + contain : '{name} must contain "{ruleValue}"', + containExactly : '{name} must contain exactly "{ruleValue}"', + doesntContain : '{name} cannot contain "{ruleValue}"', + doesntContainExactly : '{name} cannot contain exactly "{ruleValue}"', + minLength : '{name} must be at least {ruleValue} characters', + length : '{name} must be at least {ruleValue} characters', + exactLength : '{name} must be exactly {ruleValue} characters', + maxLength : '{name} cannot be longer than {ruleValue} characters', + match : '{name} must match {ruleValue} field', + different : '{name} must have a different value than {ruleValue} field', + creditCard : '{name} must be a valid credit card number', + minCount : '{name} must have at least {ruleValue} choices', + exactCount : '{name} must have exactly {ruleValue} choices', + maxCount : '{name} must have {ruleValue} or less choices' + }, + + selector : { + checkbox : 'input[type="checkbox"], input[type="radio"]', + clear : '.clear', + field : 'input:not(.search), textarea, select', + group : '.field', + input : 'input', + message : '.error.message', + prompt : '.prompt.label', + radio : 'input[type="radio"]', + reset : '.reset:not([type="reset"])', + submit : '.submit:not([type="submit"])', + uiCheckbox : '.ui.checkbox', + uiDropdown : '.ui.dropdown', + uiCalendar : '.ui.calendar' + }, + + className : { + error : 'error', + label : 'ui basic red pointing prompt label', + pressed : 'down', + success : 'success', + required : 'required', + disabled : 'disabled' + }, + + error: { + identifier : 'You must specify a string identifier for each field', + method : 'The method you called is not defined.', + noRule : 'There is no rule matching the one you specified', + oldSyntax : 'Starting in 2.0 forms now only take a single settings object. Validation settings converted to new syntax automatically.', + noElement : 'This module requires ui {element}' + }, + + templates: { + + // template that produces error message + error: function(errors) { + var + html = '<ul class="list">' + ; + $.each(errors, function(index, value) { + html += '<li>' + value + '</li>'; + }); + html += '</ul>'; + return $(html); + }, + + // template that produces label + prompt: function(errors, labelClasses) { + return $('<div/>') + .addClass(labelClasses) + .html(errors[0]) + ; + } + }, + + formatter: { + date: function(date) { + return Intl.DateTimeFormat('en-GB').format(date); + }, + datetime: function(date) { + return Intl.DateTimeFormat('en-GB', { + year: "numeric", + month: "2-digit", + day: "2-digit", + hour: '2-digit', + minute: '2-digit', + second: '2-digit' + }).format(date); + }, + time: function(date) { + return Intl.DateTimeFormat('en-GB', { + hour: '2-digit', + minute: '2-digit', + second: '2-digit' + }).format(date); + }, + month: function(date) { + return Intl.DateTimeFormat('en-GB', { + month: '2-digit', + year: 'numeric' + }).format(date); + }, + year: function(date) { + return Intl.DateTimeFormat('en-GB', { + year: 'numeric' + }).format(date); + } + }, + + rules: { + + // is not empty or blank string + empty: function(value) { + return !(value === undefined || '' === value || Array.isArray(value) && value.length === 0); + }, + + // checkbox checked + checked: function() { + return ($(this).filter(':checked').length > 0); + }, + + // is most likely an email + email: function(value){ + return $.fn.form.settings.regExp.email.test(value); + }, + + // value is most likely url + url: function(value) { + return $.fn.form.settings.regExp.url.test(value); + }, + + // matches specified regExp + regExp: function(value, regExp) { + if(regExp instanceof RegExp) { + return value.match(regExp); + } + var + regExpParts = regExp.match($.fn.form.settings.regExp.flags), + flags + ; + // regular expression specified as /baz/gi (flags) + if(regExpParts) { + regExp = (regExpParts.length >= 2) + ? regExpParts[1] + : regExp + ; + flags = (regExpParts.length >= 3) + ? regExpParts[2] + : '' + ; + } + return value.match( new RegExp(regExp, flags) ); + }, + + // is valid integer or matches range + integer: function(value, range) { + var + intRegExp = $.fn.form.settings.regExp.integer, + min, + max, + parts + ; + if( !range || ['', '..'].indexOf(range) !== -1) { + // do nothing + } + else if(range.indexOf('..') == -1) { + if(intRegExp.test(range)) { + min = max = range - 0; + } + } + else { + parts = range.split('..', 2); + if(intRegExp.test(parts[0])) { + min = parts[0] - 0; + } + if(intRegExp.test(parts[1])) { + max = parts[1] - 0; + } + } + return ( + intRegExp.test(value) && + (min === undefined || value >= min) && + (max === undefined || value <= max) + ); + }, + + // is valid number (with decimal) + decimal: function(value) { + return $.fn.form.settings.regExp.decimal.test(value); + }, + + // is valid number + number: function(value) { + return $.fn.form.settings.regExp.number.test(value); + }, + + // is value (case insensitive) + is: function(value, text) { + text = (typeof text == 'string') + ? text.toLowerCase() + : text + ; + value = (typeof value == 'string') + ? value.toLowerCase() + : value + ; + return (value == text); + }, + + // is value + isExactly: function(value, text) { + return (value == text); + }, + + // value is not another value (case insensitive) + not: function(value, notValue) { + value = (typeof value == 'string') + ? value.toLowerCase() + : value + ; + notValue = (typeof notValue == 'string') + ? notValue.toLowerCase() + : notValue + ; + return (value != notValue); + }, + + // value is not another value (case sensitive) + notExactly: function(value, notValue) { + return (value != notValue); + }, + + // value contains text (insensitive) + contains: function(value, text) { + // escape regex characters + text = text.replace($.fn.form.settings.regExp.escape, "\\$&"); + return (value.search( new RegExp(text, 'i') ) !== -1); + }, + + // value contains text (case sensitive) + containsExactly: function(value, text) { + // escape regex characters + text = text.replace($.fn.form.settings.regExp.escape, "\\$&"); + return (value.search( new RegExp(text) ) !== -1); + }, + + // value contains text (insensitive) + doesntContain: function(value, text) { + // escape regex characters + text = text.replace($.fn.form.settings.regExp.escape, "\\$&"); + return (value.search( new RegExp(text, 'i') ) === -1); + }, + + // value contains text (case sensitive) + doesntContainExactly: function(value, text) { + // escape regex characters + text = text.replace($.fn.form.settings.regExp.escape, "\\$&"); + return (value.search( new RegExp(text) ) === -1); + }, + + // is at least string length + minLength: function(value, requiredLength) { + return (value !== undefined) + ? (value.length >= requiredLength) + : false + ; + }, + + // see rls notes for 2.0.6 (this is a duplicate of minLength) + length: function(value, requiredLength) { + return (value !== undefined) + ? (value.length >= requiredLength) + : false + ; + }, + + // is exactly length + exactLength: function(value, requiredLength) { + return (value !== undefined) + ? (value.length == requiredLength) + : false + ; + }, + + // is less than length + maxLength: function(value, maxLength) { + return (value !== undefined) + ? (value.length <= maxLength) + : false + ; + }, + + // matches another field + match: function(value, identifier, $module) { + var + matchingValue, + matchingElement + ; + if((matchingElement = $module.find('[data-validate="'+ identifier +'"]')).length > 0 ) { + matchingValue = matchingElement.val(); + } + else if((matchingElement = $module.find('#' + identifier)).length > 0) { + matchingValue = matchingElement.val(); + } + else if((matchingElement = $module.find('[name="' + identifier +'"]')).length > 0) { + matchingValue = matchingElement.val(); + } + else if((matchingElement = $module.find('[name="' + identifier +'[]"]')).length > 0 ) { + matchingValue = matchingElement; + } + return (matchingValue !== undefined) + ? ( value.toString() == matchingValue.toString() ) + : false + ; + }, + + // different than another field + different: function(value, identifier, $module) { + // use either id or name of field + var + matchingValue, + matchingElement + ; + if((matchingElement = $module.find('[data-validate="'+ identifier +'"]')).length > 0 ) { + matchingValue = matchingElement.val(); + } + else if((matchingElement = $module.find('#' + identifier)).length > 0) { + matchingValue = matchingElement.val(); + } + else if((matchingElement = $module.find('[name="' + identifier +'"]')).length > 0) { + matchingValue = matchingElement.val(); + } + else if((matchingElement = $module.find('[name="' + identifier +'[]"]')).length > 0 ) { + matchingValue = matchingElement; + } + return (matchingValue !== undefined) + ? ( value.toString() !== matchingValue.toString() ) + : false + ; + }, + + creditCard: function(cardNumber, cardTypes) { + var + cards = { + visa: { + pattern : /^4/, + length : [16] + }, + amex: { + pattern : /^3[47]/, + length : [15] + }, + mastercard: { + pattern : /^5[1-5]/, + length : [16] + }, + discover: { + pattern : /^(6011|622(12[6-9]|1[3-9][0-9]|[2-8][0-9]{2}|9[0-1][0-9]|92[0-5]|64[4-9])|65)/, + length : [16] + }, + unionPay: { + pattern : /^(62|88)/, + length : [16, 17, 18, 19] + }, + jcb: { + pattern : /^35(2[89]|[3-8][0-9])/, + length : [16] + }, + maestro: { + pattern : /^(5018|5020|5038|6304|6759|676[1-3])/, + length : [12, 13, 14, 15, 16, 17, 18, 19] + }, + dinersClub: { + pattern : /^(30[0-5]|^36)/, + length : [14] + }, + laser: { + pattern : /^(6304|670[69]|6771)/, + length : [16, 17, 18, 19] + }, + visaElectron: { + pattern : /^(4026|417500|4508|4844|491(3|7))/, + length : [16] + } + }, + valid = {}, + validCard = false, + requiredTypes = (typeof cardTypes == 'string') + ? cardTypes.split(',') + : false, + unionPay, + validation + ; + + if(typeof cardNumber !== 'string' || cardNumber.length === 0) { + return; + } + + // allow dashes in card + cardNumber = cardNumber.replace(/[\-]/g, ''); + + // verify card types + if(requiredTypes) { + $.each(requiredTypes, function(index, type){ + // verify each card type + validation = cards[type]; + if(validation) { + valid = { + length : ($.inArray(cardNumber.length, validation.length) !== -1), + pattern : (cardNumber.search(validation.pattern) !== -1) + }; + if(valid.length && valid.pattern) { + validCard = true; + } + } + }); + + if(!validCard) { + return false; + } + } + + // skip luhn for UnionPay + unionPay = { + number : ($.inArray(cardNumber.length, cards.unionPay.length) !== -1), + pattern : (cardNumber.search(cards.unionPay.pattern) !== -1) + }; + if(unionPay.number && unionPay.pattern) { + return true; + } + + // verify luhn, adapted from <https://gist.github.com/2134376> + var + length = cardNumber.length, + multiple = 0, + producedValue = [ + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], + [0, 2, 4, 6, 8, 1, 3, 5, 7, 9] + ], + sum = 0 + ; + while (length--) { + sum += producedValue[multiple][parseInt(cardNumber.charAt(length), 10)]; + multiple ^= 1; + } + return (sum % 10 === 0 && sum > 0); + }, + + minCount: function(value, minCount) { + if(minCount == 0) { + return true; + } + if(minCount == 1) { + return (value !== ''); + } + return (value.split(',').length >= minCount); + }, + + exactCount: function(value, exactCount) { + if(exactCount == 0) { + return (value === ''); + } + if(exactCount == 1) { + return (value !== '' && value.search(',') === -1); + } + return (value.split(',').length == exactCount); + }, + + maxCount: function(value, maxCount) { + if(maxCount == 0) { + return false; + } + if(maxCount == 1) { + return (value.search(',') === -1); + } + return (value.split(',').length <= maxCount); + } + } + +}; + +})( jQuery, window, document ); diff --git a/semantic/src/definitions/behaviors/state.js b/semantic/src/definitions/behaviors/state.js new file mode 100644 index 0000000..149b4af --- /dev/null +++ b/semantic/src/definitions/behaviors/state.js @@ -0,0 +1,711 @@ +/*! + * # Fomantic-UI - State + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +"use strict"; + +$.isFunction = $.isFunction || function(obj) { + return typeof obj === "function" && typeof obj.nodeType !== "number"; +}; + +window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.fn.state = 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), + + returnedValue + ; + $allModules + .each(function() { + var + settings = ( $.isPlainObject(parameters) ) + ? $.extend(true, {}, $.fn.state.settings, parameters) + : $.extend({}, $.fn.state.settings), + + error = settings.error, + metadata = settings.metadata, + className = settings.className, + namespace = settings.namespace, + states = settings.states, + text = settings.text, + + eventNamespace = '.' + namespace, + moduleNamespace = namespace + '-module', + + $module = $(this), + + element = this, + instance = $module.data(moduleNamespace), + + module + ; + module = { + + initialize: function() { + module.verbose('Initializing module'); + + // allow module to guess desired state based on element + if(settings.automatic) { + module.add.defaults(); + } + + // bind events with delegated events + if(settings.context && moduleSelector !== '') { + $(settings.context) + .on(moduleSelector, 'mouseenter' + eventNamespace, module.change.text) + .on(moduleSelector, 'mouseleave' + eventNamespace, module.reset.text) + .on(moduleSelector, 'click' + eventNamespace, module.toggle.state) + ; + } + else { + $module + .on('mouseenter' + eventNamespace, module.change.text) + .on('mouseleave' + eventNamespace, module.reset.text) + .on('click' + eventNamespace, module.toggle.state) + ; + } + module.instantiate(); + }, + + instantiate: function() { + module.verbose('Storing instance of module', module); + instance = module; + $module + .data(moduleNamespace, module) + ; + }, + + destroy: function() { + module.verbose('Destroying previous module', instance); + $module + .off(eventNamespace) + .removeData(moduleNamespace) + ; + }, + + refresh: function() { + module.verbose('Refreshing selector cache'); + $module = $(element); + }, + + add: { + defaults: function() { + var + userStates = parameters && $.isPlainObject(parameters.states) + ? parameters.states + : {} + ; + $.each(settings.defaults, function(type, typeStates) { + if( module.is[type] !== undefined && module.is[type]() ) { + module.verbose('Adding default states', type, element); + $.extend(settings.states, typeStates, userStates); + } + }); + } + }, + + is: { + + active: function() { + return $module.hasClass(className.active); + }, + loading: function() { + return $module.hasClass(className.loading); + }, + inactive: function() { + return !( $module.hasClass(className.active) ); + }, + state: function(state) { + if(className[state] === undefined) { + return false; + } + return $module.hasClass( className[state] ); + }, + + enabled: function() { + return !( $module.is(settings.filter.active) ); + }, + disabled: function() { + return ( $module.is(settings.filter.active) ); + }, + textEnabled: function() { + return !( $module.is(settings.filter.text) ); + }, + + // definitions for automatic type detection + button: function() { + return $module.is('.button:not(a, .submit)'); + }, + input: function() { + return $module.is('input'); + }, + progress: function() { + return $module.is('.ui.progress'); + } + }, + + allow: function(state) { + module.debug('Now allowing state', state); + states[state] = true; + }, + disallow: function(state) { + module.debug('No longer allowing', state); + states[state] = false; + }, + + allows: function(state) { + return states[state] || false; + }, + + enable: function() { + $module.removeClass(className.disabled); + }, + + disable: function() { + $module.addClass(className.disabled); + }, + + setState: function(state) { + if(module.allows(state)) { + $module.addClass( className[state] ); + } + }, + + removeState: function(state) { + if(module.allows(state)) { + $module.removeClass( className[state] ); + } + }, + + toggle: { + state: function() { + var + apiRequest, + requestCancelled + ; + if( module.allows('active') && module.is.enabled() ) { + module.refresh(); + if($.fn.api !== undefined) { + apiRequest = $module.api('get request'); + requestCancelled = $module.api('was cancelled'); + if( requestCancelled ) { + module.debug('API Request cancelled by beforesend'); + settings.activateTest = function(){ return false; }; + settings.deactivateTest = function(){ return false; }; + } + else if(apiRequest) { + module.listenTo(apiRequest); + return; + } + } + module.change.state(); + } + } + }, + + listenTo: function(apiRequest) { + module.debug('API request detected, waiting for state signal', apiRequest); + if(apiRequest) { + if(text.loading) { + module.update.text(text.loading); + } + $.when(apiRequest) + .then(function() { + if(apiRequest.state() == 'resolved') { + module.debug('API request succeeded'); + settings.activateTest = function(){ return true; }; + settings.deactivateTest = function(){ return true; }; + } + else { + module.debug('API request failed'); + settings.activateTest = function(){ return false; }; + settings.deactivateTest = function(){ return false; }; + } + module.change.state(); + }) + ; + } + }, + + // checks whether active/inactive state can be given + change: { + + state: function() { + module.debug('Determining state change direction'); + // inactive to active change + if( module.is.inactive() ) { + module.activate(); + } + else { + module.deactivate(); + } + if(settings.sync) { + module.sync(); + } + settings.onChange.call(element); + }, + + text: function() { + if( module.is.textEnabled() ) { + if(module.is.disabled() ) { + module.verbose('Changing text to disabled text', text.hover); + module.update.text(text.disabled); + } + else if( module.is.active() ) { + if(text.hover) { + module.verbose('Changing text to hover text', text.hover); + module.update.text(text.hover); + } + else if(text.deactivate) { + module.verbose('Changing text to deactivating text', text.deactivate); + module.update.text(text.deactivate); + } + } + else { + if(text.hover) { + module.verbose('Changing text to hover text', text.hover); + module.update.text(text.hover); + } + else if(text.activate){ + module.verbose('Changing text to activating text', text.activate); + module.update.text(text.activate); + } + } + } + } + + }, + + activate: function() { + if( settings.activateTest.call(element) ) { + module.debug('Setting state to active'); + $module + .addClass(className.active) + ; + module.update.text(text.active); + settings.onActivate.call(element); + } + }, + + deactivate: function() { + if( settings.deactivateTest.call(element) ) { + module.debug('Setting state to inactive'); + $module + .removeClass(className.active) + ; + module.update.text(text.inactive); + settings.onDeactivate.call(element); + } + }, + + sync: function() { + module.verbose('Syncing other buttons to current state'); + if( module.is.active() ) { + $allModules + .not($module) + .state('activate'); + } + else { + $allModules + .not($module) + .state('deactivate') + ; + } + }, + + get: { + text: function() { + return (settings.selector.text) + ? $module.find(settings.selector.text).text() + : $module.html() + ; + }, + textFor: function(state) { + return text[state] || false; + } + }, + + flash: { + text: function(text, duration, callback) { + var + previousText = module.get.text() + ; + module.debug('Flashing text message', text, duration); + text = text || settings.text.flash; + duration = duration || settings.flashDuration; + callback = callback || function() {}; + module.update.text(text); + setTimeout(function(){ + module.update.text(previousText); + callback.call(element); + }, duration); + } + }, + + reset: { + // on mouseout sets text to previous value + text: function() { + var + activeText = text.active || $module.data(metadata.storedText), + inactiveText = text.inactive || $module.data(metadata.storedText) + ; + if( module.is.textEnabled() ) { + if( module.is.active() && activeText) { + module.verbose('Resetting active text', activeText); + module.update.text(activeText); + } + else if(inactiveText) { + module.verbose('Resetting inactive text', activeText); + module.update.text(inactiveText); + } + } + } + }, + + update: { + text: function(text) { + var + currentText = module.get.text() + ; + if(text && text !== currentText) { + module.debug('Updating text', text); + if(settings.selector.text) { + $module + .data(metadata.storedText, text) + .find(settings.selector.text) + .text(text) + ; + } + else { + $module + .data(metadata.storedText, text) + .html(text) + ; + } + } + else { + module.debug('Text is already set, ignoring update', text); + } + } + }, + + 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(Array.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.state.settings = { + + // module info + name : 'State', + + // debug output + debug : false, + + // verbose debug output + verbose : false, + + // namespace for events + namespace : 'state', + + // debug data includes performance + performance : true, + + // callback occurs on state change + onActivate : function() {}, + onDeactivate : function() {}, + onChange : function() {}, + + // state test functions + activateTest : function() { return true; }, + deactivateTest : function() { return true; }, + + // whether to automatically map default states + automatic : true, + + // activate / deactivate changes all elements instantiated at same time + sync : false, + + // default flash text duration, used for temporarily changing text of an element + flashDuration : 1000, + + // selector filter + filter : { + text : '.loading, .disabled', + active : '.disabled' + }, + + context : false, + + // error + error: { + beforeSend : 'The before send function has cancelled state change', + method : 'The method you called is not defined.' + }, + + // metadata + metadata: { + promise : 'promise', + storedText : 'stored-text' + }, + + // change class on state + className: { + active : 'active', + disabled : 'disabled', + error : 'error', + loading : 'loading', + success : 'success', + warning : 'warning' + }, + + selector: { + // selector for text node + text: false + }, + + defaults : { + input: { + disabled : true, + loading : true, + active : true + }, + button: { + disabled : true, + loading : true, + active : true, + }, + progress: { + active : true, + success : true, + warning : true, + error : true + } + }, + + states : { + active : true, + disabled : true, + error : true, + loading : true, + success : true, + warning : true + }, + + text : { + disabled : false, + flash : false, + hover : false, + active : false, + inactive : false, + activate : false, + deactivate : false + } + +}; + + + +})( jQuery, window, document ); diff --git a/semantic/src/definitions/behaviors/visibility.js b/semantic/src/definitions/behaviors/visibility.js new file mode 100644 index 0000000..4e40619 --- /dev/null +++ b/semantic/src/definitions/behaviors/visibility.js @@ -0,0 +1,1313 @@ +/*! + * # Fomantic-UI - Visibility + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +'use strict'; + +$.isFunction = $.isFunction || function(obj) { + return typeof obj === "function" && typeof obj.nodeType !== "number"; +}; + +window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.fn.visibility = 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), + returnedValue, + + moduleCount = $allModules.length, + loadedCount = 0 + ; + + $allModules + .each(function() { + var + settings = ( $.isPlainObject(parameters) ) + ? $.extend(true, {}, $.fn.visibility.settings, parameters) + : $.extend({}, $.fn.visibility.settings), + + className = settings.className, + namespace = settings.namespace, + error = settings.error, + metadata = settings.metadata, + + eventNamespace = '.' + namespace, + moduleNamespace = 'module-' + namespace, + + $window = $(window), + + $module = $(this), + $context = $(settings.context), + + $placeholder, + + instance = $module.data(moduleNamespace), + + requestAnimationFrame = window.requestAnimationFrame + || window.mozRequestAnimationFrame + || window.webkitRequestAnimationFrame + || window.msRequestAnimationFrame + || function(callback) { setTimeout(callback, 0); }, + + element = this, + disabled = false, + + contextObserver, + observer, + module + ; + + module = { + + initialize: function() { + module.debug('Initializing', settings); + + module.setup.cache(); + + if( module.should.trackChanges() ) { + + if(settings.type == 'image') { + module.setup.image(); + } + if(settings.type == 'fixed') { + module.setup.fixed(); + } + + if(settings.observeChanges) { + module.observeChanges(); + } + module.bind.events(); + } + + module.save.position(); + if( !module.is.visible() ) { + module.error(error.visible, $module); + } + + if(settings.initialCheck) { + module.checkVisibility(); + } + module.instantiate(); + }, + + instantiate: function() { + module.debug('Storing instance', module); + $module + .data(moduleNamespace, module) + ; + instance = module; + }, + + destroy: function() { + module.verbose('Destroying previous module'); + if(observer) { + observer.disconnect(); + } + if(contextObserver) { + contextObserver.disconnect(); + } + $window + .off('load' + eventNamespace, module.event.load) + .off('resize' + eventNamespace, module.event.resize) + ; + $context + .off('scroll' + eventNamespace, module.event.scroll) + .off('scrollchange' + eventNamespace, module.event.scrollchange) + ; + if(settings.type == 'fixed') { + module.resetFixed(); + module.remove.placeholder(); + } + $module + .off(eventNamespace) + .removeData(moduleNamespace) + ; + }, + + observeChanges: function() { + if('MutationObserver' in window) { + contextObserver = new MutationObserver(module.event.contextChanged); + observer = new MutationObserver(module.event.changed); + contextObserver.observe(document, { + childList : true, + subtree : true + }); + observer.observe(element, { + childList : true, + subtree : true + }); + module.debug('Setting up mutation observer', observer); + } + }, + + bind: { + events: function() { + module.verbose('Binding visibility events to scroll and resize'); + if(settings.refreshOnLoad) { + $window + .on('load' + eventNamespace, module.event.load) + ; + } + $window + .on('resize' + eventNamespace, module.event.resize) + ; + // pub/sub pattern + $context + .off('scroll' + eventNamespace) + .on('scroll' + eventNamespace, module.event.scroll) + .on('scrollchange' + eventNamespace, module.event.scrollchange) + ; + } + }, + + event: { + changed: function(mutations) { + module.verbose('DOM tree modified, updating visibility calculations'); + module.timer = setTimeout(function() { + module.verbose('DOM tree modified, updating sticky menu'); + module.refresh(); + }, 100); + }, + contextChanged: function(mutations) { + [].forEach.call(mutations, function(mutation) { + if(mutation.removedNodes) { + [].forEach.call(mutation.removedNodes, function(node) { + if(node == element || $(node).find(element).length > 0) { + module.debug('Element removed from DOM, tearing down events'); + module.destroy(); + } + }); + } + }); + }, + resize: function() { + module.debug('Window resized'); + if(settings.refreshOnResize) { + requestAnimationFrame(module.refresh); + } + }, + load: function() { + module.debug('Page finished loading'); + requestAnimationFrame(module.refresh); + }, + // publishes scrollchange event on one scroll + scroll: function() { + if(settings.throttle) { + clearTimeout(module.timer); + module.timer = setTimeout(function() { + $context.triggerHandler('scrollchange' + eventNamespace, [ $context.scrollTop() ]); + }, settings.throttle); + } + else { + requestAnimationFrame(function() { + $context.triggerHandler('scrollchange' + eventNamespace, [ $context.scrollTop() ]); + }); + } + }, + // subscribes to scrollchange + scrollchange: function(event, scrollPosition) { + module.checkVisibility(scrollPosition); + }, + }, + + precache: function(images, callback) { + if (!(images instanceof Array)) { + images = [images]; + } + var + imagesLength = images.length, + loadedCounter = 0, + cache = [], + cacheImage = document.createElement('img'), + handleLoad = function() { + loadedCounter++; + if (loadedCounter >= images.length) { + if ($.isFunction(callback)) { + callback(); + } + } + } + ; + while (imagesLength--) { + cacheImage = document.createElement('img'); + cacheImage.onload = handleLoad; + cacheImage.onerror = handleLoad; + cacheImage.src = images[imagesLength]; + cache.push(cacheImage); + } + }, + + enableCallbacks: function() { + module.debug('Allowing callbacks to occur'); + disabled = false; + }, + + disableCallbacks: function() { + module.debug('Disabling all callbacks temporarily'); + disabled = true; + }, + + should: { + trackChanges: function() { + if(methodInvoked) { + module.debug('One time query, no need to bind events'); + return false; + } + module.debug('Callbacks being attached'); + return true; + } + }, + + setup: { + cache: function() { + module.cache = { + occurred : {}, + screen : {}, + element : {}, + }; + }, + image: function() { + var + src = $module.data(metadata.src) + ; + if(src) { + module.verbose('Lazy loading image', src); + settings.once = true; + settings.observeChanges = false; + + // show when top visible + settings.onOnScreen = function() { + module.debug('Image on screen', element); + module.precache(src, function() { + module.set.image(src, function() { + loadedCount++; + if(loadedCount == moduleCount) { + settings.onAllLoaded.call(this); + } + settings.onLoad.call(this); + }); + }); + }; + } + }, + fixed: function() { + module.debug('Setting up fixed'); + settings.once = false; + settings.observeChanges = false; + settings.initialCheck = true; + settings.refreshOnLoad = true; + if(!parameters.transition) { + settings.transition = false; + } + module.create.placeholder(); + module.debug('Added placeholder', $placeholder); + settings.onTopPassed = function() { + module.debug('Element passed, adding fixed position', $module); + module.show.placeholder(); + module.set.fixed(); + if(settings.transition) { + if($.fn.transition !== undefined) { + $module.transition(settings.transition, settings.duration); + } + } + }; + settings.onTopPassedReverse = function() { + module.debug('Element returned to position, removing fixed', $module); + module.hide.placeholder(); + module.remove.fixed(); + }; + } + }, + + create: { + placeholder: function() { + module.verbose('Creating fixed position placeholder'); + $placeholder = $module + .clone(false) + .css('display', 'none') + .addClass(className.placeholder) + .insertAfter($module) + ; + } + }, + + show: { + placeholder: function() { + module.verbose('Showing placeholder'); + $placeholder + .css('display', 'block') + .css('visibility', 'hidden') + ; + } + }, + hide: { + placeholder: function() { + module.verbose('Hiding placeholder'); + $placeholder + .css('display', 'none') + .css('visibility', '') + ; + } + }, + + set: { + fixed: function() { + module.verbose('Setting element to fixed position'); + $module + .addClass(className.fixed) + .css({ + position : 'fixed', + top : settings.offset + 'px', + left : 'auto', + zIndex : settings.zIndex + }) + ; + settings.onFixed.call(element); + }, + image: function(src, callback) { + $module + .attr('src', src) + ; + if(settings.transition) { + if( $.fn.transition !== undefined) { + if($module.hasClass(className.visible)) { + module.debug('Transition already occurred on this image, skipping animation'); + return; + } + $module.transition(settings.transition, settings.duration, callback); + } + else { + $module.fadeIn(settings.duration, callback); + } + } + else { + $module.show(); + } + } + }, + + is: { + onScreen: function() { + var + calculations = module.get.elementCalculations() + ; + return calculations.onScreen; + }, + offScreen: function() { + var + calculations = module.get.elementCalculations() + ; + return calculations.offScreen; + }, + visible: function() { + if(module.cache && module.cache.element) { + return !(module.cache.element.width === 0 && module.cache.element.offset.top === 0); + } + return false; + }, + verticallyScrollableContext: function() { + var + overflowY = ($context.get(0) !== window) + ? $context.css('overflow-y') + : false + ; + return (overflowY == 'auto' || overflowY == 'scroll'); + }, + horizontallyScrollableContext: function() { + var + overflowX = ($context.get(0) !== window) + ? $context.css('overflow-x') + : false + ; + return (overflowX == 'auto' || overflowX == 'scroll'); + } + }, + + refresh: function() { + module.debug('Refreshing constants (width/height)'); + if(settings.type == 'fixed') { + module.resetFixed(); + } + module.reset(); + module.save.position(); + if(settings.checkOnRefresh) { + module.checkVisibility(); + } + settings.onRefresh.call(element); + }, + + resetFixed: function () { + module.remove.fixed(); + module.remove.occurred(); + }, + + reset: function() { + module.verbose('Resetting all cached values'); + if( $.isPlainObject(module.cache) ) { + module.cache.screen = {}; + module.cache.element = {}; + } + }, + + checkVisibility: function(scroll) { + module.verbose('Checking visibility of element', module.cache.element); + + if( !disabled && module.is.visible() ) { + + // save scroll position + module.save.scroll(scroll); + + // update calculations derived from scroll + module.save.calculations(); + + // percentage + module.passed(); + + // reverse (must be first) + module.passingReverse(); + module.topVisibleReverse(); + module.bottomVisibleReverse(); + module.topPassedReverse(); + module.bottomPassedReverse(); + + // one time + module.onScreen(); + module.offScreen(); + module.passing(); + module.topVisible(); + module.bottomVisible(); + module.topPassed(); + module.bottomPassed(); + + // on update callback + if(settings.onUpdate) { + settings.onUpdate.call(element, module.get.elementCalculations()); + } + } + }, + + passed: function(amount, newCallback) { + var + calculations = module.get.elementCalculations() + ; + // assign callback + if(amount && newCallback) { + settings.onPassed[amount] = newCallback; + } + else if(amount !== undefined) { + return (module.get.pixelsPassed(amount) > calculations.pixelsPassed); + } + else if(calculations.passing) { + $.each(settings.onPassed, function(amount, callback) { + if(calculations.bottomVisible || calculations.pixelsPassed > module.get.pixelsPassed(amount)) { + module.execute(callback, amount); + } + else if(!settings.once) { + module.remove.occurred(callback); + } + }); + } + }, + + onScreen: function(newCallback) { + var + calculations = module.get.elementCalculations(), + callback = newCallback || settings.onOnScreen, + callbackName = 'onScreen' + ; + if(newCallback) { + module.debug('Adding callback for onScreen', newCallback); + settings.onOnScreen = newCallback; + } + if(calculations.onScreen) { + module.execute(callback, callbackName); + } + else if(!settings.once) { + module.remove.occurred(callbackName); + } + if(newCallback !== undefined) { + return calculations.onOnScreen; + } + }, + + offScreen: function(newCallback) { + var + calculations = module.get.elementCalculations(), + callback = newCallback || settings.onOffScreen, + callbackName = 'offScreen' + ; + if(newCallback) { + module.debug('Adding callback for offScreen', newCallback); + settings.onOffScreen = newCallback; + } + if(calculations.offScreen) { + module.execute(callback, callbackName); + } + else if(!settings.once) { + module.remove.occurred(callbackName); + } + if(newCallback !== undefined) { + return calculations.onOffScreen; + } + }, + + passing: function(newCallback) { + var + calculations = module.get.elementCalculations(), + callback = newCallback || settings.onPassing, + callbackName = 'passing' + ; + if(newCallback) { + module.debug('Adding callback for passing', newCallback); + settings.onPassing = newCallback; + } + if(calculations.passing) { + module.execute(callback, callbackName); + } + else if(!settings.once) { + module.remove.occurred(callbackName); + } + if(newCallback !== undefined) { + return calculations.passing; + } + }, + + + topVisible: function(newCallback) { + var + calculations = module.get.elementCalculations(), + callback = newCallback || settings.onTopVisible, + callbackName = 'topVisible' + ; + if(newCallback) { + module.debug('Adding callback for top visible', newCallback); + settings.onTopVisible = newCallback; + } + if(calculations.topVisible) { + module.execute(callback, callbackName); + } + else if(!settings.once) { + module.remove.occurred(callbackName); + } + if(newCallback === undefined) { + return calculations.topVisible; + } + }, + + bottomVisible: function(newCallback) { + var + calculations = module.get.elementCalculations(), + callback = newCallback || settings.onBottomVisible, + callbackName = 'bottomVisible' + ; + if(newCallback) { + module.debug('Adding callback for bottom visible', newCallback); + settings.onBottomVisible = newCallback; + } + if(calculations.bottomVisible) { + module.execute(callback, callbackName); + } + else if(!settings.once) { + module.remove.occurred(callbackName); + } + if(newCallback === undefined) { + return calculations.bottomVisible; + } + }, + + topPassed: function(newCallback) { + var + calculations = module.get.elementCalculations(), + callback = newCallback || settings.onTopPassed, + callbackName = 'topPassed' + ; + if(newCallback) { + module.debug('Adding callback for top passed', newCallback); + settings.onTopPassed = newCallback; + } + if(calculations.topPassed) { + module.execute(callback, callbackName); + } + else if(!settings.once) { + module.remove.occurred(callbackName); + } + if(newCallback === undefined) { + return calculations.topPassed; + } + }, + + bottomPassed: function(newCallback) { + var + calculations = module.get.elementCalculations(), + callback = newCallback || settings.onBottomPassed, + callbackName = 'bottomPassed' + ; + if(newCallback) { + module.debug('Adding callback for bottom passed', newCallback); + settings.onBottomPassed = newCallback; + } + if(calculations.bottomPassed) { + module.execute(callback, callbackName); + } + else if(!settings.once) { + module.remove.occurred(callbackName); + } + if(newCallback === undefined) { + return calculations.bottomPassed; + } + }, + + passingReverse: function(newCallback) { + var + calculations = module.get.elementCalculations(), + callback = newCallback || settings.onPassingReverse, + callbackName = 'passingReverse' + ; + if(newCallback) { + module.debug('Adding callback for passing reverse', newCallback); + settings.onPassingReverse = newCallback; + } + if(!calculations.passing) { + if(module.get.occurred('passing')) { + module.execute(callback, callbackName); + } + } + else if(!settings.once) { + module.remove.occurred(callbackName); + } + if(newCallback !== undefined) { + return !calculations.passing; + } + }, + + + topVisibleReverse: function(newCallback) { + var + calculations = module.get.elementCalculations(), + callback = newCallback || settings.onTopVisibleReverse, + callbackName = 'topVisibleReverse' + ; + if(newCallback) { + module.debug('Adding callback for top visible reverse', newCallback); + settings.onTopVisibleReverse = newCallback; + } + if(!calculations.topVisible) { + if(module.get.occurred('topVisible')) { + module.execute(callback, callbackName); + } + } + else if(!settings.once) { + module.remove.occurred(callbackName); + } + if(newCallback === undefined) { + return !calculations.topVisible; + } + }, + + bottomVisibleReverse: function(newCallback) { + var + calculations = module.get.elementCalculations(), + callback = newCallback || settings.onBottomVisibleReverse, + callbackName = 'bottomVisibleReverse' + ; + if(newCallback) { + module.debug('Adding callback for bottom visible reverse', newCallback); + settings.onBottomVisibleReverse = newCallback; + } + if(!calculations.bottomVisible) { + if(module.get.occurred('bottomVisible')) { + module.execute(callback, callbackName); + } + } + else if(!settings.once) { + module.remove.occurred(callbackName); + } + if(newCallback === undefined) { + return !calculations.bottomVisible; + } + }, + + topPassedReverse: function(newCallback) { + var + calculations = module.get.elementCalculations(), + callback = newCallback || settings.onTopPassedReverse, + callbackName = 'topPassedReverse' + ; + if(newCallback) { + module.debug('Adding callback for top passed reverse', newCallback); + settings.onTopPassedReverse = newCallback; + } + if(!calculations.topPassed) { + if(module.get.occurred('topPassed')) { + module.execute(callback, callbackName); + } + } + else if(!settings.once) { + module.remove.occurred(callbackName); + } + if(newCallback === undefined) { + return !calculations.onTopPassed; + } + }, + + bottomPassedReverse: function(newCallback) { + var + calculations = module.get.elementCalculations(), + callback = newCallback || settings.onBottomPassedReverse, + callbackName = 'bottomPassedReverse' + ; + if(newCallback) { + module.debug('Adding callback for bottom passed reverse', newCallback); + settings.onBottomPassedReverse = newCallback; + } + if(!calculations.bottomPassed) { + if(module.get.occurred('bottomPassed')) { + module.execute(callback, callbackName); + } + } + else if(!settings.once) { + module.remove.occurred(callbackName); + } + if(newCallback === undefined) { + return !calculations.bottomPassed; + } + }, + + execute: function(callback, callbackName) { + var + calculations = module.get.elementCalculations(), + screen = module.get.screenCalculations() + ; + callback = callback || false; + if(callback) { + if(settings.continuous) { + module.debug('Callback being called continuously', callbackName, calculations); + callback.call(element, calculations, screen); + } + else if(!module.get.occurred(callbackName)) { + module.debug('Conditions met', callbackName, calculations); + callback.call(element, calculations, screen); + } + } + module.save.occurred(callbackName); + }, + + remove: { + fixed: function() { + module.debug('Removing fixed position'); + $module + .removeClass(className.fixed) + .css({ + position : '', + top : '', + left : '', + zIndex : '' + }) + ; + settings.onUnfixed.call(element); + }, + placeholder: function() { + module.debug('Removing placeholder content'); + if($placeholder) { + $placeholder.remove(); + } + }, + occurred: function(callback) { + if(callback) { + var + occurred = module.cache.occurred + ; + if(occurred[callback] !== undefined && occurred[callback] === true) { + module.debug('Callback can now be called again', callback); + module.cache.occurred[callback] = false; + } + } + else { + module.cache.occurred = {}; + } + } + }, + + save: { + calculations: function() { + module.verbose('Saving all calculations necessary to determine positioning'); + module.save.direction(); + module.save.screenCalculations(); + module.save.elementCalculations(); + }, + occurred: function(callback) { + if(callback) { + if(module.cache.occurred[callback] === undefined || (module.cache.occurred[callback] !== true)) { + module.verbose('Saving callback occurred', callback); + module.cache.occurred[callback] = true; + } + } + }, + scroll: function(scrollPosition) { + scrollPosition = scrollPosition + settings.offset || $context.scrollTop() + settings.offset; + module.cache.scroll = scrollPosition; + }, + direction: function() { + var + scroll = module.get.scroll(), + lastScroll = module.get.lastScroll(), + direction + ; + if(scroll > lastScroll && lastScroll) { + direction = 'down'; + } + else if(scroll < lastScroll && lastScroll) { + direction = 'up'; + } + else { + direction = 'static'; + } + module.cache.direction = direction; + return module.cache.direction; + }, + elementPosition: function() { + var + element = module.cache.element, + screen = module.get.screenSize() + ; + module.verbose('Saving element position'); + // (quicker than $.extend) + element.fits = (element.height < screen.height); + element.offset = $module.offset(); + element.width = $module.outerWidth(); + element.height = $module.outerHeight(); + // compensate for scroll in context + if(module.is.verticallyScrollableContext()) { + element.offset.top += $context.scrollTop() - $context.offset().top; + } + if(module.is.horizontallyScrollableContext()) { + element.offset.left += $context.scrollLeft() - $context.offset().left; + } + // store + module.cache.element = element; + return element; + }, + elementCalculations: function() { + var + screen = module.get.screenCalculations(), + element = module.get.elementPosition() + ; + // offset + if(settings.includeMargin) { + element.margin = {}; + element.margin.top = parseInt($module.css('margin-top'), 10); + element.margin.bottom = parseInt($module.css('margin-bottom'), 10); + element.top = element.offset.top - element.margin.top; + element.bottom = element.offset.top + element.height + element.margin.bottom; + } + else { + element.top = element.offset.top; + element.bottom = element.offset.top + element.height; + } + + // visibility + element.topPassed = (screen.top >= element.top); + element.bottomPassed = (screen.top >= element.bottom); + element.topVisible = (screen.bottom >= element.top) && !element.topPassed; + element.bottomVisible = (screen.bottom >= element.bottom) && !element.bottomPassed; + element.pixelsPassed = 0; + element.percentagePassed = 0; + + // meta calculations + element.onScreen = ((element.topVisible || element.passing) && !element.bottomPassed); + element.passing = (element.topPassed && !element.bottomPassed); + element.offScreen = (!element.onScreen); + + // passing calculations + if(element.passing) { + element.pixelsPassed = (screen.top - element.top); + element.percentagePassed = (screen.top - element.top) / element.height; + } + module.cache.element = element; + module.verbose('Updated element calculations', element); + return element; + }, + screenCalculations: function() { + var + scroll = module.get.scroll() + ; + module.save.direction(); + module.cache.screen.top = scroll; + module.cache.screen.bottom = scroll + module.cache.screen.height; + return module.cache.screen; + }, + screenSize: function() { + module.verbose('Saving window position'); + module.cache.screen = { + height: $context.height() + }; + }, + position: function() { + module.save.screenSize(); + module.save.elementPosition(); + } + }, + + get: { + pixelsPassed: function(amount) { + var + element = module.get.elementCalculations() + ; + if(amount.search('%') > -1) { + return ( element.height * (parseInt(amount, 10) / 100) ); + } + return parseInt(amount, 10); + }, + occurred: function(callback) { + return (module.cache.occurred !== undefined) + ? module.cache.occurred[callback] || false + : false + ; + }, + direction: function() { + if(module.cache.direction === undefined) { + module.save.direction(); + } + return module.cache.direction; + }, + elementPosition: function() { + if(module.cache.element === undefined) { + module.save.elementPosition(); + } + return module.cache.element; + }, + elementCalculations: function() { + if(module.cache.element === undefined) { + module.save.elementCalculations(); + } + return module.cache.element; + }, + screenCalculations: function() { + if(module.cache.screen === undefined) { + module.save.screenCalculations(); + } + return module.cache.screen; + }, + screenSize: function() { + if(module.cache.screen === undefined) { + module.save.screenSize(); + } + return module.cache.screen; + }, + scroll: function() { + if(module.cache.scroll === undefined) { + module.save.scroll(); + } + return module.cache.scroll; + }, + lastScroll: function() { + if(module.cache.screen === undefined) { + module.debug('First scroll event, no last scroll could be found'); + return false; + } + return module.cache.screen.top; + } + }, + + setting: function(name, value) { + if( $.isPlainObject(name) ) { + $.extend(true, settings, name); + } + else if(value !== undefined) { + 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(Array.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(); + } + instance.save.scroll(); + instance.save.calculations(); + module.invoke(query); + } + else { + if(instance !== undefined) { + instance.invoke('destroy'); + } + module.initialize(); + } + }) + ; + + return (returnedValue !== undefined) + ? returnedValue + : this + ; +}; + +$.fn.visibility.settings = { + + name : 'Visibility', + namespace : 'visibility', + + debug : false, + verbose : false, + performance : true, + + // whether to use mutation observers to follow changes + observeChanges : true, + + // check position immediately on init + initialCheck : true, + + // whether to refresh calculations after all page images load + refreshOnLoad : true, + + // whether to refresh calculations after page resize event + refreshOnResize : true, + + // should call callbacks on refresh event (resize, etc) + checkOnRefresh : true, + + // callback should only occur one time + once : true, + + // callback should fire continuously whe evaluates to true + continuous : false, + + // offset to use with scroll top + offset : 0, + + // whether to include margin in elements position + includeMargin : false, + + // scroll context for visibility checks + context : window, + + // visibility check delay in ms (defaults to animationFrame) + throttle : false, + + // special visibility type (image, fixed) + type : false, + + // z-index to use with visibility 'fixed' + zIndex : '10', + + // image only animation settings + transition : 'fade in', + duration : 1000, + + // array of callbacks for percentage + onPassed : {}, + + // standard callbacks + onOnScreen : false, + onOffScreen : false, + onPassing : false, + onTopVisible : false, + onBottomVisible : false, + onTopPassed : false, + onBottomPassed : false, + + // reverse callbacks + onPassingReverse : false, + onTopVisibleReverse : false, + onBottomVisibleReverse : false, + onTopPassedReverse : false, + onBottomPassedReverse : false, + + // special callbacks for image + onLoad : function() {}, + onAllLoaded : function() {}, + + // special callbacks for fixed position + onFixed : function() {}, + onUnfixed : function() {}, + + // utility callbacks + onUpdate : false, // disabled by default for performance + onRefresh : function(){}, + + metadata : { + src: 'src' + }, + + className: { + fixed : 'fixed', + placeholder : 'constraint', + visible : 'visible' + }, + + error : { + method : 'The method you called is not defined.', + visible : 'Element is hidden, you must call refresh after element becomes visible' + } + +}; + +})( jQuery, window, document ); diff --git a/semantic/src/definitions/collections/breadcrumb.less b/semantic/src/definitions/collections/breadcrumb.less new file mode 100644 index 0000000..df6f979 --- /dev/null +++ b/semantic/src/definitions/collections/breadcrumb.less @@ -0,0 +1,122 @@ +/*! + * # Fomantic-UI - Breadcrumb + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +/******************************* + Theme +*******************************/ + +@type : 'collection'; +@element : 'breadcrumb'; + +@import (multiple) '../../theme.config'; + + +/******************************* + Breadcrumb +*******************************/ + +.ui.breadcrumb { + line-height: @lineHeight; + display: @display; + margin: @verticalMargin 0; + vertical-align: @verticalAlign; +} +.ui.breadcrumb:first-child { + margin-top: 0; +} +.ui.breadcrumb:last-child { + margin-bottom: 0; +} + +/******************************* + Content +*******************************/ + +/* Divider */ +.ui.breadcrumb .divider { + display: inline-block; + opacity: @dividerOpacity; + margin: 0 @dividerSpacing 0; + + font-size: @dividerSize; + color: @dividerColor; + vertical-align: @dividerVerticalAlign; +} + +/* Link */ +.ui.breadcrumb a { + color: @linkColor; +} +.ui.breadcrumb a:hover { + color: @linkHoverColor; +} + + +/* Icon Divider */ +.ui.breadcrumb .icon.divider { + font-size: @iconDividerSize; + vertical-align: @iconDividerVerticalAlign; +} + +/* Section */ +.ui.breadcrumb a.section { + cursor: pointer; +} +.ui.breadcrumb .section { + display: inline-block; + margin: @sectionMargin; + padding: @sectionPadding; +} + +/* Loose Coupling */ +.ui.breadcrumb.segment { + display: inline-block; + padding: @segmentPadding; +} + +& when (@variationBreadcrumbInverted) { + /* Inverted */ + .ui.inverted.breadcrumb { + color: @invertedColor; + } + .ui.inverted.breadcrumb > .active.section { + color: @invertedActiveColor; + } + .ui.inverted.breadcrumb > .divider { + color: @invertedDividerColor; + } +} + +/******************************* + States +*******************************/ + +.ui.breadcrumb .active.section { + font-weight: @activeFontWeight; +} + + +/******************************* + Variations +*******************************/ + +.ui.breadcrumb { + font-size: @medium; +} +& when not (@variationBreadcrumbSizes = false) { + each(@variationBreadcrumbSizes, { + @s: @@value; + .ui.@{value}.breadcrumb { + font-size: @s; + } + }) +} + +.loadUIOverrides(); diff --git a/semantic/src/definitions/collections/form.less b/semantic/src/definitions/collections/form.less new file mode 100644 index 0000000..3cde7f1 --- /dev/null +++ b/semantic/src/definitions/collections/form.less @@ -0,0 +1,1112 @@ +/*! + * # Fomantic-UI - Form + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +/******************************* + Theme +*******************************/ + +@type : 'collection'; +@element : 'form'; + +@import (multiple) '../../theme.config'; + +/******************************* + Elements +*******************************/ + +/*-------------------- + Form +---------------------*/ + +.ui.form { + position: relative; + max-width: 100%; +} + +/*-------------------- + Content +---------------------*/ + +.ui.form > p { + margin: @paragraphMargin; +} + +/*-------------------- + Field +---------------------*/ + +.ui.form .field { + clear: both; + margin: @fieldMargin; +} + +.ui.form .fields .fields, +.ui.form .field:last-child, +.ui.form .fields:last-child .field { + margin-bottom: 0; +} + +.ui.form .fields .field { + clear: both; + margin: 0; +} + + +/*-------------------- + Labels +---------------------*/ + +.ui.form .field > label { + display: block; + margin: @labelMargin; + color: @labelColor; + font-size: @labelFontSize; + font-weight: @labelFontWeight; + text-transform: @labelTextTransform; +} + +/*-------------------- + Standard Inputs +---------------------*/ + + +.ui.form textarea, +.ui.form input:not([type]), +.ui.form input[type="date"], +.ui.form input[type="datetime-local"], +.ui.form input[type="email"], +.ui.form input[type="number"], +.ui.form input[type="password"], +.ui.form input[type="search"], +.ui.form input[type="tel"], +.ui.form input[type="time"], +.ui.form input[type="text"], +.ui.form input[type="file"], +.ui.form input[type="url"] { + width: @inputWidth; + vertical-align: top; +} + +/* Set max height on unusual input */ +.ui.form ::-webkit-datetime-edit, +.ui.form ::-webkit-inner-spin-button { + height: @inputLineHeight; +} + +.ui.form input:not([type]), +.ui.form input[type="date"], +.ui.form input[type="datetime-local"], +.ui.form input[type="email"], +.ui.form input[type="number"], +.ui.form input[type="password"], +.ui.form input[type="search"], +.ui.form input[type="tel"], +.ui.form input[type="time"], +.ui.form input[type="text"], +.ui.form input[type="file"], +.ui.form input[type="url"] { + font-family: @inputFont; + margin: 0; + outline: none; + -webkit-appearance: none; + -webkit-tap-highlight-color: rgba(255, 255, 255, 0); + + line-height: @inputLineHeight; + padding: @inputPadding; + font-size: @inputFontSize; + + background: @inputBackground; + border: @inputBorder; + color: @inputColor; + border-radius: @inputBorderRadius; + box-shadow: @inputBoxShadow; + transition: @inputTransition; +} + +/* Text Area */ +.ui.input textarea, +.ui.form textarea { + margin: 0; + -webkit-appearance: none; + -webkit-tap-highlight-color: rgba(255, 255, 255, 0); + + padding: @textAreaPadding; + background: @textAreaBackground; + border: @textAreaBorder; + outline: none; + color: @inputColor; + border-radius: @inputBorderRadius; + box-shadow: @inputBoxShadow; + transition: @textAreaTransition; + font-size: @textAreaFontSize; + font-family: @inputFont; + line-height: @textAreaLineHeight; + resize: @textAreaResize; +} +.ui.form textarea:not([rows]) { + height: @textAreaHeight; + min-height: @textAreaMinHeight; + max-height: @textAreaMaxHeight; +} + +.ui.form textarea, +.ui.form input[type="checkbox"] { + vertical-align: @checkboxVerticalAlign; +} + +/*-------------------- + Checkbox margin +---------------------*/ + +.ui.form .fields:not(.grouped):not(.inline) .field:not(:only-child) label + .ui.ui.checkbox { + margin-top: @checkboxLabelFieldTopMargin; +} +.ui.form .fields:not(.grouped):not(.inline) .field:not(:only-child) .ui.checkbox { + margin-top: @inputLineHeight + @checkboxFieldTopMargin; +} +.ui.form .fields:not(.grouped):not(.inline) .field:not(:only-child) .ui.toggle.checkbox { + margin-top: @inputLineHeight + @checkboxToggleFieldTopMargin; +} +.ui.form .fields:not(.grouped):not(.inline) .field:not(:only-child) .ui.slider.checkbox { + margin-top: @inputLineHeight + @checkboxSliderFieldTopMargin; +} +.ui.ui.form .field .fields .field:not(:only-child) .ui.checkbox { + margin-top: @checkboxFieldTopMargin / 2; +} +.ui.ui.form .field .fields .field:not(:only-child) .ui.toggle.checkbox { + margin-top: @checkboxToggleFieldTopMargin / 2; +} +.ui.ui.form .field .fields .field:not(:only-child) .ui.slider.checkbox { + margin-top: @checkboxSliderFieldTopMargin / 2; +} + +& when (@variationFormTransparent) { + /*-------------------- + Transparent + ---------------------*/ + + .ui.form .field .transparent.input:not(.icon) input, + .ui.form .field input.transparent, + .ui.form .field textarea.transparent { + padding: @transparentPadding; + } + + .ui.form .field input.transparent, + .ui.form .field textarea.transparent { + border-color: transparent !important; + background-color: transparent !important; + box-shadow: none !important; + } +} +/*-------------------------- + Input w/ attached Button +---------------------------*/ + +.ui.form input.attached { + width: auto; +} + + +/*-------------------- + Basic Select +---------------------*/ + +.ui.form select { + display: block; + height: auto; + width: 100%; + background: @selectBackground; + border: @selectBorder; + border-radius: @selectBorderRadius; + box-shadow: @selectBoxShadow; + padding: @selectPadding; + color: @selectColor; + transition: @selectTransition; +} + +/*-------------------- + Dropdown +---------------------*/ + +/* Block */ +.ui.form .field > .selection.dropdown { + min-width: auto; + width: 100%; +} +.ui.form .field > .selection.dropdown > .dropdown.icon { + float: right; +} + +& when (@variationFormInline) { + /* Inline */ + .ui.form .inline.fields .field > .selection.dropdown, + .ui.form .inline.field > .selection.dropdown { + width: auto; + } + .ui.form .inline.fields .field > .selection.dropdown > .dropdown.icon, + .ui.form .inline.field > .selection.dropdown > .dropdown.icon { + float: none; + } +} + +/*-------------------- + UI Input +---------------------*/ + +/* Block */ +.ui.form .field .ui.input, +.ui.form .fields .field .ui.input, +.ui.form .wide.field .ui.input { + width: 100%; +} + +& when (@variationFormInline) { + /* Inline */ + .ui.form .inline.fields .field:not(.wide) .ui.input, + .ui.form .inline.field:not(.wide) .ui.input { + width: auto; + vertical-align: middle; + } +} + +/* Auto Input */ +.ui.form .fields .field .ui.input input, +.ui.form .field .ui.input input { + width: auto; +} + +/* Full Width Input */ +.ui.form .ten.fields .ui.input input, +.ui.form .nine.fields .ui.input input, +.ui.form .eight.fields .ui.input input, +.ui.form .seven.fields .ui.input input, +.ui.form .six.fields .ui.input input, +.ui.form .five.fields .ui.input input, +.ui.form .four.fields .ui.input input, +.ui.form .three.fields .ui.input input, +.ui.form .two.fields .ui.input input, +.ui.form .wide.field .ui.input input { + flex: 1 0 auto; + width: 0; +} + + +/*-------------------- + Types of Messages +---------------------*/ +& when (@variationFormStates) { + each(@formStates, { + @state: replace(@key, '@', ''); + .ui.form .@{state}.message, + .ui.form .@{state}.message:empty { + display: none; + } + }) +} + +/* Assumptions */ +.ui.form .message:first-child { + margin-top: 0; +} + +/*-------------------- + Validation Prompt +---------------------*/ + +.ui.form .field .prompt.label { + white-space: normal; + background: @promptBackground !important; + border: @promptBorder !important; + color: @promptTextColor !important; +} +& when (@variationFormInline) { + .ui.form .inline.fields .field .prompt, + .ui.form .inline.field .prompt { + vertical-align: top; + margin: @inlinePromptMargin; + } + .ui.form .inline.fields .field .prompt:before, + .ui.form .inline.field .prompt:before { + border-width: 0 0 @inlinePromptBorderWidth @inlinePromptBorderWidth; + bottom: auto; + right: auto; + top: 50%; + left: 0; + } +} + + +/******************************* + States +*******************************/ + +/*-------------------- + Autofilled +---------------------*/ + +.ui.form .field.field input:-webkit-autofill { + box-shadow: 0 0 0 100px @inputAutoFillBackground inset !important; + border-color: @inputAutoFillBorder !important; +} + +/* Focus */ +.ui.form .field.field input:-webkit-autofill:focus { + box-shadow: 0 0 0 100px @inputAutoFillFocusBackground inset !important; + border-color: @inputAutoFillFocusBorder !important; +} + + + +/*-------------------- + Placeholder +---------------------*/ + +/* browsers require these rules separate */ +.ui.form ::-webkit-input-placeholder { + color: @inputPlaceholderColor; +} +.ui.form :-ms-input-placeholder { + color: @inputPlaceholderColor !important; +} +.ui.form ::-moz-placeholder { + color: @inputPlaceholderColor; +} + +.ui.form :focus::-webkit-input-placeholder { + color: @inputPlaceholderFocusColor; +} +.ui.form :focus:-ms-input-placeholder { + color: @inputPlaceholderFocusColor !important; +} +.ui.form :focus::-moz-placeholder { + color: @inputPlaceholderFocusColor; +} + + + +/*-------------------- + Focus +---------------------*/ + +.ui.form input:not([type]):focus, +.ui.form input[type="date"]:focus, +.ui.form input[type="datetime-local"]:focus, +.ui.form input[type="email"]:focus, +.ui.form input[type="number"]:focus, +.ui.form input[type="password"]:focus, +.ui.form input[type="search"]:focus, +.ui.form input[type="tel"]:focus, +.ui.form input[type="time"]:focus, +.ui.form input[type="text"]:focus, +.ui.form input[type="file"]:focus, +.ui.form input[type="url"]:focus { + color: @inputFocusColor; + border-color: @inputFocusBorderColor; + border-radius: @inputFocusBorderRadius; + background: @inputFocusBackground; + box-shadow: @inputFocusBoxShadow; +} +& when (@variationInputAction) { + .ui.form .ui.action.input:not([class*="left action"]) { + & input:not([type]):focus, + input[type="date"]:focus, + input[type="datetime-local"]:focus, + input[type="email"]:focus, + input[type="number"]:focus, + input[type="password"]:focus, + input[type="search"]:focus, + input[type="tel"]:focus, + input[type="time"]:focus, + input[type="text"]:focus, + input[type="file"]:focus, + input[type="url"]:focus { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + } + + .ui.form .ui[class*="left action"].input { + & input:not([type]), + input[type="date"], + input[type="datetime-local"], + input[type="email"], + input[type="number"], + input[type="password"], + input[type="search"], + input[type="tel"], + input[type="time"], + input[type="text"], + input[type="file"], + input[type="url"] { + border-bottom-left-radius: 0; + border-top-left-radius: 0; + } + } +} +.ui.form textarea:focus { + color: @textAreaFocusColor; + border-color: @textAreaFocusBorderColor; + border-radius: @textAreaFocusBorderRadius; + background: @textAreaFocusBackground; + box-shadow: @textAreaFocusBoxShadow; + -webkit-appearance: none; +} + +& when (@variationFormStates) { + /*-------------------- + States + ---------------------*/ + each(@formStates, { + @state: replace(@key, '@', ''); + @c: @formStates[@@state][color]; + @bg: @formStates[@@state][background]; + @bdc: @formStates[@@state][borderColor]; + + /* On Form */ + .ui.form.@{state} .@{state}.message:not(:empty) { + display: block; + } + .ui.form.@{state} .compact.@{state}.message:not(:empty) { + display: inline-block; + } + .ui.form.@{state} .icon.@{state}.message:not(:empty) { + display: flex; + } + + /* On Field(s) */ + .ui.form .fields.@{state} .@{state}.message:not(:empty), + .ui.form .field.@{state} .@{state}.message:not(:empty) { + display: block; + } + .ui.form .fields.@{state} .compact.@{state}.message:not(:empty), + .ui.form .field.@{state} .compact.@{state}.message:not(:empty) { + display: inline-block; + } + .ui.form .fields.@{state} .icon.@{state}.message:not(:empty), + .ui.form .field.@{state} .icon.@{state}.message:not(:empty) { + display: flex; + } + + .ui.ui.form .fields.@{state} .field label, + .ui.ui.form .field.@{state} label, + .ui.ui.form .fields.@{state} .field .input, + .ui.ui.form .field.@{state} .input { + color: @c; + } + + .ui.form .fields.@{state} .field .corner.label, + .ui.form .field.@{state} .corner.label { + border-color: @c; + color: @formStates[@@state][cornerLabelColor]; + } + + .ui.form .fields.@{state} .field textarea, + .ui.form .fields.@{state} .field select, + .ui.form .fields.@{state} .field input:not([type]), + .ui.form .fields.@{state} .field input[type="date"], + .ui.form .fields.@{state} .field input[type="datetime-local"], + .ui.form .fields.@{state} .field input[type="email"], + .ui.form .fields.@{state} .field input[type="number"], + .ui.form .fields.@{state} .field input[type="password"], + .ui.form .fields.@{state} .field input[type="search"], + .ui.form .fields.@{state} .field input[type="tel"], + .ui.form .fields.@{state} .field input[type="time"], + .ui.form .fields.@{state} .field input[type="text"], + .ui.form .fields.@{state} .field input[type="file"], + .ui.form .fields.@{state} .field input[type="url"], + .ui.form .field.@{state} textarea, + .ui.form .field.@{state} select, + .ui.form .field.@{state} input:not([type]), + .ui.form .field.@{state} input[type="date"], + .ui.form .field.@{state} input[type="datetime-local"], + .ui.form .field.@{state} input[type="email"], + .ui.form .field.@{state} input[type="number"], + .ui.form .field.@{state} input[type="password"], + .ui.form .field.@{state} input[type="search"], + .ui.form .field.@{state} input[type="tel"], + .ui.form .field.@{state} input[type="time"], + .ui.form .field.@{state} input[type="text"], + .ui.form .field.@{state} input[type="file"], + .ui.form .field.@{state} input[type="url"] { + color: @c; + background: @bg; + border-color: @formStates[@@state][borderColor]; + border-radius: @formStates[@@state][borderRadius]; + box-shadow: @formStates[@@state][boxShadow]; + } + + .ui.form .field.@{state} textarea:focus, + .ui.form .field.@{state} select:focus, + .ui.form .field.@{state} input:not([type]):focus, + .ui.form .field.@{state} input[type="date"]:focus, + .ui.form .field.@{state} input[type="datetime-local"]:focus, + .ui.form .field.@{state} input[type="email"]:focus, + .ui.form .field.@{state} input[type="number"]:focus, + .ui.form .field.@{state} input[type="password"]:focus, + .ui.form .field.@{state} input[type="search"]:focus, + .ui.form .field.@{state} input[type="tel"]:focus, + .ui.form .field.@{state} input[type="time"]:focus, + .ui.form .field.@{state} input[type="text"]:focus, + .ui.form .field.@{state} input[type="file"]:focus, + .ui.form .field.@{state} input[type="url"]:focus { + background: @formStates[@@state][inputFocusBackground]; + border-color: @formStates[@@state][inputFocusBorderColor]; + color: @formStates[@@state][inputFocusColor]; + + box-shadow: @formStates[@@state][inputFocusBoxShadow]; + } + + /* Preserve Native Select Stylings */ + .ui.form .field.@{state} select { + -webkit-appearance: menulist-button; + } + + /*------------------ + Input State + --------------------*/ + /* Transparent */ + .ui.form .field.@{state} .transparent.input input, + .ui.form .field.@{state} .transparent.input textarea, + .ui.form .field.@{state} input.transparent, + .ui.form .field.@{state} textarea.transparent { + background-color: @formStates[@@state][transparentBackground] !important; + color: @formStates[@@state][transparentColor] !important; + } + + /* Autofilled */ + .ui.form .@{state}.@{state} input:-webkit-autofill { + box-shadow: 0 0 0 100px @formStates[@@state][inputAutoFillBackground] inset !important; + border-color: @formStates[@@state][inputAutoFillBorderColor] !important; + } + + /* Placeholder */ + .ui.form .@{state} ::-webkit-input-placeholder { + color: @formStates[@@state][inputPlaceholderColor]; + } + .ui.form .@{state} :-ms-input-placeholder { + color: @formStates[@@state][inputPlaceholderColor] !important; + } + .ui.form .@{state} ::-moz-placeholder { + color: @formStates[@@state][inputPlaceholderColor]; + } + + .ui.form .@{state} :focus::-webkit-input-placeholder { + color: @formStates[@@state][inputPlaceholderFocusColor]; + } + .ui.form .@{state} :focus:-ms-input-placeholder { + color: @formStates[@@state][inputPlaceholderFocusColor] !important; + } + .ui.form .@{state} :focus::-moz-placeholder { + color: @formStates[@@state][inputPlaceholderFocusColor]; + } + + /*------------------ + Dropdown State + --------------------*/ + + .ui.form .fields.@{state} .field .ui.dropdown, + .ui.form .fields.@{state} .field .ui.dropdown .item, + .ui.form .field.@{state} .ui.dropdown, + .ui.form .field.@{state} .ui.dropdown .text, + .ui.form .field.@{state} .ui.dropdown .item { + background: @bg; + color: @c; + } + .ui.form .fields.@{state} .field .ui.dropdown, + .ui.form .field.@{state} .ui.dropdown { + border-color: @bdc !important; + } + .ui.form .fields.@{state} .field .ui.dropdown:hover, + .ui.form .field.@{state} .ui.dropdown:hover { + border-color: @bdc !important; + } + .ui.form .fields.@{state} .field .ui.dropdown:hover .menu, + .ui.form .field.@{state} .ui.dropdown:hover .menu { + border-color: @bdc; + } + .ui.form .fields.@{state} .field .ui.multiple.selection.dropdown > .label, + .ui.form .field.@{state} .ui.multiple.selection.dropdown > .label { + background-color: @formStates[@@state][dropdownLabelBackground]; + color: @formStates[@@state][dropdownLabelColor]; + } + + /* Hover */ + .ui.form .fields.@{state} .field .ui.dropdown .menu .item:hover, + .ui.form .field.@{state} .ui.dropdown .menu .item:hover { + background-color: @formStates[@@state][dropdownHoverBackground]; + } + + /* Selected */ + .ui.form .fields.@{state} .field .ui.dropdown .menu .selected.item, + .ui.form .field.@{state} .ui.dropdown .menu .selected.item { + background-color: @formStates[@@state][dropdownSelectedBackground]; + } + + /* Active */ + .ui.form .fields.@{state} .field .ui.dropdown .menu .active.item, + .ui.form .field.@{state} .ui.dropdown .menu .active.item { + background-color: @formStates[@@state][dropdownActiveBackground] !important; + } + + /*-------------------- + Checkbox State + ---------------------*/ + .ui.form .fields.@{state} .field .checkbox:not(.toggle):not(.slider) label, + .ui.form .field.@{state} .checkbox:not(.toggle):not(.slider) label, + .ui.form .fields.@{state} .field .checkbox:not(.toggle):not(.slider) .box, + .ui.form .field.@{state} .checkbox:not(.toggle):not(.slider) .box { + color: @c; + } + .ui.form .fields.@{state} .field .checkbox:not(.toggle):not(.slider) label:before, + .ui.form .field.@{state} .checkbox:not(.toggle):not(.slider) label:before, + .ui.form .fields.@{state} .field .checkbox:not(.toggle):not(.slider) .box:before, + .ui.form .field.@{state} .checkbox:not(.toggle):not(.slider) .box:before { + background: @bg; + border-color: @bdc; + } + .ui.form .fields.@{state} .field .checkbox label:after, + .ui.form .field.@{state} .checkbox label:after, + .ui.form .fields.@{state} .field .checkbox .box:after, + .ui.form .field.@{state} .checkbox .box:after { + color: @c; + } + }) +} + +& when (@variationFormDisabled) { + /*-------------------- + Disabled + ---------------------*/ + + .ui.form .disabled.fields .field, + .ui.form .disabled.field, + .ui.form .field :disabled { + pointer-events: none; + opacity: @disabledOpacity; + } + .ui.form .field.disabled > label, + .ui.form .fields.disabled > label { + opacity: @disabledLabelOpacity; + } + .ui.form .field.disabled :disabled { + opacity: 1; + } +} + +& when (@variationFormLoading) { + /*-------------- + Loading + ---------------*/ + + .ui.loading.form { + position: relative; + cursor: default; + pointer-events: none; + } + .ui.loading.form:before { + position: absolute; + content: ''; + top: 0; + left: 0; + background: @loaderDimmerColor; + width: 100%; + height: 100%; + z-index: @loaderDimmerZIndex; + } + + .ui.loading.form.segments:before { + border-radius: @defaultBorderRadius; + } + + .ui.loading.form:after { + position: absolute; + content: ''; + top: 50%; + left: 50%; + + margin: @loaderMargin; + width: @loaderSize; + height: @loaderSize; + + animation: loader @loaderSpeed infinite linear; + border: @loaderLineWidth solid @loaderLineColor; + border-radius: @circularRadius; + + box-shadow: 0 0 0 1px transparent; + visibility: visible; + z-index: @loaderLineZIndex; + } +} + +/******************************* + Element Types +*******************************/ + +& when (@variationFormRequired) { + /*-------------------- + Required Field + ---------------------*/ + + .ui.form .required.fields:not(.grouped) > .field > label:after, + .ui.form .required.fields.grouped > label:after, + .ui.form .required.field > label:after, + .ui.form .required.fields:not(.grouped) > .field > .checkbox:after, + .ui.form .required.field > .checkbox:after, + .ui.form label.required:after { + margin: @requiredMargin; + content: @requiredContent; + color: @requiredColor; + } + + .ui.form .required.fields:not(.grouped) > .field > label:after, + .ui.form .required.fields.grouped > label:after, + .ui.form .required.field > label:after, + .ui.form label.required:after { + display: inline-block; + vertical-align: top; + } + + .ui.form .required.fields:not(.grouped) > .field > .checkbox:after, + .ui.form .required.field > .checkbox:after { + position: absolute; + top: 0; + left: 100%; + } +} + + +/******************************* + Variations +*******************************/ + +& when (@variationFormInverted) { + /*-------------------- + Inverted Colors + ---------------------*/ + + .ui.inverted.form label, + .ui.form .inverted.segment label, + .ui.form .inverted.segment .ui.checkbox label, + .ui.form .inverted.segment .ui.checkbox .box, + .ui.inverted.form .ui.checkbox label, + .ui.inverted.form .ui.checkbox .box, + .ui.inverted.form .inline.fields > label, + .ui.inverted.form .inline.fields .field > label, + .ui.inverted.form .inline.fields .field > p, + .ui.inverted.form .inline.field > label, + .ui.inverted.form .inline.field > p { + color: @invertedLabelColor; + } + .ui.inverted.loading.form { + color: @invertedLoaderLineColor; + } + .ui.inverted.loading.form:before { + background: @loaderInvertedDimmerColor; + } + /* Inverted Field */ + .ui.inverted.form input:not([type]), + .ui.inverted.form input[type="date"], + .ui.inverted.form input[type="datetime-local"], + .ui.inverted.form input[type="email"], + .ui.inverted.form input[type="number"], + .ui.inverted.form input[type="password"], + .ui.inverted.form input[type="search"], + .ui.inverted.form input[type="tel"], + .ui.inverted.form input[type="time"], + .ui.inverted.form input[type="text"], + .ui.inverted.form input[type="file"], + .ui.inverted.form input[type="url"] { + background: @invertedInputBackground; + border-color: @invertedInputBorderColor; + color: @invertedInputColor; + box-shadow: @invertedInputBoxShadow; + } +} + +& when (@variationFormGrouped) { + /*-------------------- + Field Groups + ---------------------*/ + + /* Grouped Vertically */ + + .ui.form .grouped.fields { + display: block; + margin: @groupedMargin; + } + + .ui.form .grouped.fields:last-child { + margin-bottom: 0; + } + + .ui.form .grouped.fields > label { + margin: @groupedLabelMargin; + color: @groupedLabelColor; + font-size: @groupedLabelFontSize; + font-weight: @groupedLabelFontWeight; + text-transform: @groupedLabelTextTransform; + } + + .ui.form .grouped.fields .field, + .ui.form .grouped.inline.fields .field { + display: block; + margin: @groupedFieldMargin; + padding: 0; + } + .ui.form .grouped.inline.fields .ui.checkbox { + margin-bottom: @groupedInlineCheckboxBottomMargin; + } +} + +/*-------------------- + Fields +---------------------*/ + +/* Split fields */ +.ui.form .fields { + display: flex; + flex-direction: row; + margin: @fieldsMargin; +} +.ui.form .fields > .field { + flex: 0 1 auto; + padding-left: (@gutterWidth / 2); + padding-right: (@gutterWidth / 2); +} +.ui.form .fields > .field:first-child { + border-left: none; + box-shadow: none; +} + +/* Other Combinations */ +.ui.form .two.fields > .fields, +.ui.form .two.fields > .field { + width: @twoColumn; +} +.ui.form .three.fields > .fields, +.ui.form .three.fields > .field { + width: @threeColumn; +} +.ui.form .four.fields > .fields, +.ui.form .four.fields > .field { + width: @fourColumn; +} +.ui.form .five.fields > .fields, +.ui.form .five.fields > .field { + width: @fiveColumn; +} +.ui.form .six.fields > .fields, +.ui.form .six.fields > .field { + width: @sixColumn; +} +.ui.form .seven.fields > .fields, +.ui.form .seven.fields > .field { + width: @sevenColumn; +} +.ui.form .eight.fields > .fields, +.ui.form .eight.fields > .field { + width: @eightColumn; +} +.ui.form .nine.fields > .fields, +.ui.form .nine.fields > .field { + width: @nineColumn; +} +.ui.form .ten.fields > .fields, +.ui.form .ten.fields > .field { + width: @tenColumn; +} + +/* Swap to full width on mobile */ +@media only screen and (max-width : @largestMobileScreen) { + .ui.form .fields { + flex-wrap: wrap; + margin-bottom: 0; + } + + .ui.form:not(.unstackable) .fields:not(.unstackable) > .fields, + .ui.form:not(.unstackable) .fields:not(.unstackable) > .field { + width: @oneColumn; + margin: 0 0 @rowDistance; + } +} + + +/* Sizing Combinations */ +.ui.form .fields .wide.field { + width: @oneWide; + padding-left: (@gutterWidth / 2); + padding-right: (@gutterWidth / 2); +} + +.ui.form .one.wide.field { + width: @oneWide; +} +.ui.form .two.wide.field { + width: @twoWide; +} +.ui.form .three.wide.field { + width: @threeWide; +} +.ui.form .four.wide.field { + width: @fourWide; +} +.ui.form .five.wide.field { + width: @fiveWide; +} +.ui.form .six.wide.field { + width: @sixWide; +} +.ui.form .seven.wide.field { + width: @sevenWide; +} +.ui.form .eight.wide.field { + width: @eightWide; +} +.ui.form .nine.wide.field { + width: @nineWide; +} +.ui.form .ten.wide.field { + width: @tenWide; +} +.ui.form .eleven.wide.field { + width: @elevenWide; +} +.ui.form .twelve.wide.field { + width: @twelveWide; +} +.ui.form .thirteen.wide.field { + width: @thirteenWide; +} +.ui.form .fourteen.wide.field { + width: @fourteenWide; +} +.ui.form .fifteen.wide.field { + width: @fifteenWide; +} +.ui.form .sixteen.wide.field { + width: @sixteenWide; +} + + +/*-------------------- + Equal Width +---------------------*/ + +.ui[class*="equal width"].form .fields > .field, +.ui.form [class*="equal width"].fields > .field { + width: 100%; + flex: 1 1 auto; +} + +& when (@variationFormInline) { + /*-------------------- + Inline Fields + ---------------------*/ + + .ui.form .inline.fields { + margin: @fieldMargin; + align-items: center; + } + .ui.form .inline.fields .field { + margin: 0; + padding: @inlineFieldsMargin; + } + + /* Inline Label */ + .ui.form .inline.fields > label, + .ui.form .inline.fields .field > label, + .ui.form .inline.fields .field > p, + .ui.form .inline.field > label, + .ui.form .inline.field > p { + display: inline-block; + width: auto; + margin-top: 0; + margin-bottom: 0; + vertical-align: baseline; + font-size: @inlineLabelFontSize; + font-weight: @inlineLabelFontWeight; + color: @inlineLabelColor; + text-transform: @inlineLabelTextTransform; + } + + /* Grouped Inline Label */ + .ui.form .inline.fields > label { + margin: @groupedInlineLabelMargin; + } + + /* Inline Input */ + .ui.form .inline.fields .field > input, + .ui.form .inline.fields .field > select, + .ui.form .inline.field > input, + .ui.form .inline.field > select { + display: inline-block; + width: auto; + + margin-top: 0; + margin-bottom: 0; + + vertical-align: middle; + font-size: @inlineInputSize; + } + + .ui.form .inline.fields .field .calendar:not(.popup), + .ui.form .inline.field .calendar:not(.popup) { + display:inline-block; + } + + .ui.form .inline.fields .field .calendar:not(.popup) > .input > input, + .ui.form .inline.field .calendar:not(.popup) > .input > input { + width: @inlineCalendarWidth; + } + + /* Label */ + .ui.form .inline.fields .field > :first-child, + .ui.form .inline.field > :first-child { + margin: 0 @inlineLabelDistance 0 0; + } + .ui.form .inline.fields .field > :only-child, + .ui.form .inline.field > :only-child { + margin: 0; + } + + /* Wide */ + .ui.form .inline.fields .wide.field { + display: flex; + align-items: center; + } + .ui.form .inline.fields .wide.field > input, + .ui.form .inline.fields .wide.field > select { + width: 100%; + } +} + + +/*-------------------- + Sizes +---------------------*/ + +.ui.form, +.ui.form .field .dropdown, +.ui.form .field .dropdown .menu > .item { + font-size: @medium; +} +& when not (@variationFormSizes = false) { + each(@variationFormSizes, { + @s: @@value; + .ui.@{value}.form, + .ui.@{value}.form .field .dropdown, + .ui.@{value}.form .field .dropdown .menu > .item { + font-size: @s; + } + }) +} + + +.loadUIOverrides(); diff --git a/semantic/src/definitions/collections/grid.less b/semantic/src/definitions/collections/grid.less new file mode 100644 index 0000000..1b5e252 --- /dev/null +++ b/semantic/src/definitions/collections/grid.less @@ -0,0 +1,1947 @@ +/*! + * # Fomantic-UI - Grid + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +/******************************* + Theme +*******************************/ + +@type : 'collection'; +@element : 'grid'; + +@import (multiple) '../../theme.config'; + +/******************************* + Standard +*******************************/ + +.ui.grid { + display: flex; + flex-direction: row; + flex-wrap: wrap; + align-items: stretch; + padding: 0; +} + +/*---------------------- + Remove Gutters +-----------------------*/ + +.ui.grid { + margin-top: -(@rowSpacing / 2); + margin-bottom: -(@rowSpacing / 2); + margin-left: -(@gutterWidth / 2); + margin-right: -(@gutterWidth / 2); +} +.ui.relaxed.grid { + margin-left: -(@relaxedGutterWidth / 2); + margin-right: -(@relaxedGutterWidth / 2); +} +.ui[class*="very relaxed"].grid { + margin-left: -(@veryRelaxedGutterWidth / 2); + margin-right: -(@veryRelaxedGutterWidth / 2); +} + + +/* Preserve Rows Spacing on Consecutive Grids */ +.ui.grid + .grid { + margin-top: @consecutiveGridDistance; +} + +/*------------------- + Columns +--------------------*/ + +/* Standard 16 column */ +.ui.grid > .column:not(.row), +.ui.grid > .row > .column { + position: relative; + display: inline-block; + + width: @oneWide; + padding-left: (@gutterWidth / 2); + padding-right: (@gutterWidth / 2); + vertical-align: top; +} + +.ui.grid > * { + padding-left: (@gutterWidth / 2); + padding-right: (@gutterWidth / 2); +} + +/*------------------- + Rows +--------------------*/ + +.ui.grid > .row { + position: relative; + display: flex; + flex-direction: row; + flex-wrap: wrap; + justify-content: inherit; + align-items: stretch; + width: 100% !important; + padding: 0; + padding-top: (@rowSpacing / 2); + padding-bottom: (@rowSpacing / 2); +} + +/*------------------- + Columns +--------------------*/ + +/* Vertical padding when no rows */ +.ui.grid > .column:not(.row) { + padding-top: (@rowSpacing / 2); + padding-bottom: (@rowSpacing / 2); +} +.ui.grid > .row > .column { + margin-top: 0; + margin-bottom: 0; +} + +/*------------------- + Content +--------------------*/ + +.ui.grid > .row > img, +.ui.grid > .row > .column > img { + max-width: @columnMaxImageWidth; +} + +/*------------------- + Loose Coupling +--------------------*/ + +/* Collapse Margin on Consecutive Grid */ +.ui.grid > .ui.grid:first-child { + margin-top: 0; +} +.ui.grid > .ui.grid:last-child { + margin-bottom: 0; +} + +/* Segment inside Aligned Grid */ +.ui.grid .aligned.row > .column > .segment:not(.compact):not(.attached), +.ui.aligned.grid .column > .segment:not(.compact):not(.attached) { + width: 100%; +} + +/* Align Dividers with Gutter */ +.ui.grid .row + .ui.divider { + flex-grow: 1; + margin: (@rowSpacing / 2) (@gutterWidth / 2); +} +.ui.grid .column + .ui.vertical.divider { + height: e(%("calc(50%% - %d)", @rowSpacing / 2)); +} + +/* Remove Border on Last Horizontal Segment */ +.ui.grid > .row > .column:last-child > .horizontal.segment, +.ui.grid > .column:last-child > .horizontal.segment { + box-shadow: none; +} + +/******************************* + Variations +*******************************/ + +& when (@variationGridPage) { + /*----------------------- + Page Grid + -------------------------*/ + + @media only screen and (max-width: @largestMobileScreen) { + .ui.page.grid { + width: @mobileWidth; + padding-left: @mobileGutter; + padding-right: @mobileGutter; + margin-left: 0; + margin-right: 0; + } + } + @media only screen and (min-width: @tabletBreakpoint) and (max-width: @largestTabletScreen) { + .ui.page.grid { + width: @tabletWidth; + margin-left: @tabletMargin; + margin-right: @tabletMargin; + padding-left: @tabletGutter; + padding-right: @tabletGutter; + } + } + @media only screen and (min-width: @computerBreakpoint) and (max-width: @largestSmallMonitor) { + .ui.page.grid { + width: @computerWidth; + margin-left: @computerMargin; + margin-right: @computerMargin; + padding-left: @computerGutter; + padding-right: @computerGutter; + } + } + @media only screen and (min-width: @largeMonitorBreakpoint) and (max-width: @largestLargeMonitor) { + .ui.page.grid { + width: @largeMonitorWidth; + margin-left: @largeMonitorMargin; + margin-right: @largeMonitorMargin; + padding-left: @largeMonitorGutter; + padding-right: @largeMonitorGutter; + } + } + @media only screen and (min-width: @widescreenMonitorBreakpoint) { + .ui.page.grid { + width: @widescreenMonitorWidth; + margin-left: @widescreenMargin; + margin-right: @widescreenMargin; + padding-left: @widescreenMonitorGutter; + padding-right: @widescreenMonitorGutter; + } + } +} + + +/*------------------- + Column Count +--------------------*/ + +/* Assume full width with one column */ +.ui.grid > .column:only-child, +.ui.grid > .row > .column:only-child { + width: @oneColumn; +} + +/* Grid Based */ +.ui[class*="one column"].grid > .row > .column, +.ui[class*="one column"].grid > .column:not(.row) { + width: @oneColumn; +} +.ui[class*="two column"].grid > .row > .column, +.ui[class*="two column"].grid > .column:not(.row) { + width: @twoColumn; +} +.ui[class*="three column"].grid > .row > .column, +.ui[class*="three column"].grid > .column:not(.row) { + width: @threeColumn; +} +.ui[class*="four column"].grid > .row > .column, +.ui[class*="four column"].grid > .column:not(.row) { + width: @fourColumn; +} +.ui[class*="five column"].grid > .row > .column, +.ui[class*="five column"].grid > .column:not(.row) { + width: @fiveColumn; +} +.ui[class*="six column"].grid > .row > .column, +.ui[class*="six column"].grid > .column:not(.row) { + width: @sixColumn; +} +.ui[class*="seven column"].grid > .row > .column, +.ui[class*="seven column"].grid > .column:not(.row) { + width: @sevenColumn; +} +.ui[class*="eight column"].grid > .row > .column, +.ui[class*="eight column"].grid > .column:not(.row) { + width: @eightColumn; +} +.ui[class*="nine column"].grid > .row > .column, +.ui[class*="nine column"].grid > .column:not(.row) { + width: @nineColumn; +} +.ui[class*="ten column"].grid > .row > .column, +.ui[class*="ten column"].grid > .column:not(.row) { + width: @tenColumn; +} +.ui[class*="eleven column"].grid > .row > .column, +.ui[class*="eleven column"].grid > .column:not(.row) { + width: @elevenColumn; +} +.ui[class*="twelve column"].grid > .row > .column, +.ui[class*="twelve column"].grid > .column:not(.row) { + width: @twelveColumn; +} +.ui[class*="thirteen column"].grid > .row > .column, +.ui[class*="thirteen column"].grid > .column:not(.row) { + width: @thirteenColumn; +} +.ui[class*="fourteen column"].grid > .row > .column, +.ui[class*="fourteen column"].grid > .column:not(.row) { + width: @fourteenColumn; +} +.ui[class*="fifteen column"].grid > .row > .column, +.ui[class*="fifteen column"].grid > .column:not(.row) { + width: @fifteenColumn; +} +.ui[class*="sixteen column"].grid > .row > .column, +.ui[class*="sixteen column"].grid > .column:not(.row) { + width: @sixteenColumn; +} + +/* Row Based Overrides */ +.ui.grid > [class*="one column"].row > .column { + width: @oneColumn !important; +} +.ui.grid > [class*="two column"].row > .column { + width: @twoColumn !important; +} +.ui.grid > [class*="three column"].row > .column { + width: @threeColumn !important; +} +.ui.grid > [class*="four column"].row > .column { + width: @fourColumn !important; +} +.ui.grid > [class*="five column"].row > .column { + width: @fiveColumn !important; +} +.ui.grid > [class*="six column"].row > .column { + width: @sixColumn !important; +} +.ui.grid > [class*="seven column"].row > .column { + width: @sevenColumn !important; +} +.ui.grid > [class*="eight column"].row > .column { + width: @eightColumn !important; +} +.ui.grid > [class*="nine column"].row > .column { + width: @nineColumn !important; +} +.ui.grid > [class*="ten column"].row > .column { + width: @tenColumn !important; +} +.ui.grid > [class*="eleven column"].row > .column { + width: @elevenColumn !important; +} +.ui.grid > [class*="twelve column"].row > .column { + width: @twelveColumn !important; +} +.ui.grid > [class*="thirteen column"].row > .column { + width: @thirteenColumn !important; +} +.ui.grid > [class*="fourteen column"].row > .column { + width: @fourteenColumn !important; +} +.ui.grid > [class*="fifteen column"].row > .column { + width: @fifteenColumn !important; +} +.ui.grid > [class*="sixteen column"].row > .column { + width: @sixteenColumn !important; +} + +& when (@variationGridCelled) and (@variationGridPage){ + /* Celled Page */ + .ui.celled.page.grid { + box-shadow: none; + } +} + +/*------------------- + Column Width +--------------------*/ + +/* Sizing Combinations */ +.ui.grid > .row > [class*="one wide"].column, +.ui.grid > .column.row > [class*="one wide"].column, +.ui.grid > [class*="one wide"].column, +.ui.column.grid > [class*="one wide"].column { + width: @oneWide !important; +} +.ui.grid > .row > [class*="two wide"].column, +.ui.grid > .column.row > [class*="two wide"].column, +.ui.grid > [class*="two wide"].column, +.ui.column.grid > [class*="two wide"].column { + width: @twoWide !important; +} +.ui.grid > .row > [class*="three wide"].column, +.ui.grid > .column.row > [class*="three wide"].column, +.ui.grid > [class*="three wide"].column, +.ui.column.grid > [class*="three wide"].column { + width: @threeWide !important; +} +.ui.grid > .row > [class*="four wide"].column, +.ui.grid > .column.row > [class*="four wide"].column, +.ui.grid > [class*="four wide"].column, +.ui.column.grid > [class*="four wide"].column { + width: @fourWide !important; +} +.ui.grid > .row > [class*="five wide"].column, +.ui.grid > .column.row > [class*="five wide"].column, +.ui.grid > [class*="five wide"].column, +.ui.column.grid > [class*="five wide"].column { + width: @fiveWide !important; +} +.ui.grid > .row > [class*="six wide"].column, +.ui.grid > .column.row > [class*="six wide"].column, +.ui.grid > [class*="six wide"].column, +.ui.column.grid > [class*="six wide"].column { + width: @sixWide !important; +} +.ui.grid > .row > [class*="seven wide"].column, +.ui.grid > .column.row > [class*="seven wide"].column, +.ui.grid > [class*="seven wide"].column, +.ui.column.grid > [class*="seven wide"].column { + width: @sevenWide !important; +} +.ui.grid > .row > [class*="eight wide"].column, +.ui.grid > .column.row > [class*="eight wide"].column, +.ui.grid > [class*="eight wide"].column, +.ui.column.grid > [class*="eight wide"].column { + width: @eightWide !important; +} +.ui.grid > .row > [class*="nine wide"].column, +.ui.grid > .column.row > [class*="nine wide"].column, +.ui.grid > [class*="nine wide"].column, +.ui.column.grid > [class*="nine wide"].column { + width: @nineWide !important; +} +.ui.grid > .row > [class*="ten wide"].column, +.ui.grid > .column.row > [class*="ten wide"].column, +.ui.grid > [class*="ten wide"].column, +.ui.column.grid > [class*="ten wide"].column { + width: @tenWide !important; +} +.ui.grid > .row > [class*="eleven wide"].column, +.ui.grid > .column.row > [class*="eleven wide"].column, +.ui.grid > [class*="eleven wide"].column, +.ui.column.grid > [class*="eleven wide"].column { + width: @elevenWide !important; +} +.ui.grid > .row > [class*="twelve wide"].column, +.ui.grid > .column.row > [class*="twelve wide"].column, +.ui.grid > [class*="twelve wide"].column, +.ui.column.grid > [class*="twelve wide"].column { + width: @twelveWide !important; +} +.ui.grid > .row > [class*="thirteen wide"].column, +.ui.grid > .column.row > [class*="thirteen wide"].column, +.ui.grid > [class*="thirteen wide"].column, +.ui.column.grid > [class*="thirteen wide"].column { + width: @thirteenWide !important; +} +.ui.grid > .row > [class*="fourteen wide"].column, +.ui.grid > .column.row > [class*="fourteen wide"].column, +.ui.grid > [class*="fourteen wide"].column, +.ui.column.grid > [class*="fourteen wide"].column { + width: @fourteenWide !important; +} +.ui.grid > .row > [class*="fifteen wide"].column, +.ui.grid > .column.row > [class*="fifteen wide"].column, +.ui.grid > [class*="fifteen wide"].column, +.ui.column.grid > [class*="fifteen wide"].column { + width: @fifteenWide !important; +} +.ui.grid > .row > [class*="sixteen wide"].column, +.ui.grid > .column.row > [class*="sixteen wide"].column, +.ui.grid > [class*="sixteen wide"].column, +.ui.column.grid > [class*="sixteen wide"].column { + width: @sixteenWide !important; +} + +/*---------------------- + Width per Device +-----------------------*/ + +/* Mobile Sizing Combinations */ +@media only screen and (min-width: @mobileBreakpoint) and (max-width: @largestMobileScreen) { + .ui.grid > .row > [class*="one wide mobile"].column, + .ui.grid > .column.row > [class*="one wide mobile"].column, + .ui.grid > [class*="one wide mobile"].column, + .ui.column.grid > [class*="one wide mobile"].column { + width: @oneWide !important; + } + .ui.grid > .row > [class*="two wide mobile"].column, + .ui.grid > .column.row > [class*="two wide mobile"].column, + .ui.grid > [class*="two wide mobile"].column, + .ui.column.grid > [class*="two wide mobile"].column { + width: @twoWide !important; + } + .ui.grid > .row > [class*="three wide mobile"].column, + .ui.grid > .column.row > [class*="three wide mobile"].column, + .ui.grid > [class*="three wide mobile"].column, + .ui.column.grid > [class*="three wide mobile"].column { + width: @threeWide !important; + } + .ui.grid > .row > [class*="four wide mobile"].column, + .ui.grid > .column.row > [class*="four wide mobile"].column, + .ui.grid > [class*="four wide mobile"].column, + .ui.column.grid > [class*="four wide mobile"].column { + width: @fourWide !important; + } + .ui.grid > .row > [class*="five wide mobile"].column, + .ui.grid > .column.row > [class*="five wide mobile"].column, + .ui.grid > [class*="five wide mobile"].column, + .ui.column.grid > [class*="five wide mobile"].column { + width: @fiveWide !important; + } + .ui.grid > .row > [class*="six wide mobile"].column, + .ui.grid > .column.row > [class*="six wide mobile"].column, + .ui.grid > [class*="six wide mobile"].column, + .ui.column.grid > [class*="six wide mobile"].column { + width: @sixWide !important; + } + .ui.grid > .row > [class*="seven wide mobile"].column, + .ui.grid > .column.row > [class*="seven wide mobile"].column, + .ui.grid > [class*="seven wide mobile"].column, + .ui.column.grid > [class*="seven wide mobile"].column { + width: @sevenWide !important; + } + .ui.grid > .row > [class*="eight wide mobile"].column, + .ui.grid > .column.row > [class*="eight wide mobile"].column, + .ui.grid > [class*="eight wide mobile"].column, + .ui.column.grid > [class*="eight wide mobile"].column { + width: @eightWide !important; + } + .ui.grid > .row > [class*="nine wide mobile"].column, + .ui.grid > .column.row > [class*="nine wide mobile"].column, + .ui.grid > [class*="nine wide mobile"].column, + .ui.column.grid > [class*="nine wide mobile"].column { + width: @nineWide !important; + } + .ui.grid > .row > [class*="ten wide mobile"].column, + .ui.grid > .column.row > [class*="ten wide mobile"].column, + .ui.grid > [class*="ten wide mobile"].column, + .ui.column.grid > [class*="ten wide mobile"].column { + width: @tenWide !important; + } + .ui.grid > .row > [class*="eleven wide mobile"].column, + .ui.grid > .column.row > [class*="eleven wide mobile"].column, + .ui.grid > [class*="eleven wide mobile"].column, + .ui.column.grid > [class*="eleven wide mobile"].column { + width: @elevenWide !important; + } + .ui.grid > .row > [class*="twelve wide mobile"].column, + .ui.grid > .column.row > [class*="twelve wide mobile"].column, + .ui.grid > [class*="twelve wide mobile"].column, + .ui.column.grid > [class*="twelve wide mobile"].column { + width: @twelveWide !important; + } + .ui.grid > .row > [class*="thirteen wide mobile"].column, + .ui.grid > .column.row > [class*="thirteen wide mobile"].column, + .ui.grid > [class*="thirteen wide mobile"].column, + .ui.column.grid > [class*="thirteen wide mobile"].column { + width: @thirteenWide !important; + } + .ui.grid > .row > [class*="fourteen wide mobile"].column, + .ui.grid > .column.row > [class*="fourteen wide mobile"].column, + .ui.grid > [class*="fourteen wide mobile"].column, + .ui.column.grid > [class*="fourteen wide mobile"].column { + width: @fourteenWide !important; + } + .ui.grid > .row > [class*="fifteen wide mobile"].column, + .ui.grid > .column.row > [class*="fifteen wide mobile"].column, + .ui.grid > [class*="fifteen wide mobile"].column, + .ui.column.grid > [class*="fifteen wide mobile"].column { + width: @fifteenWide !important; + } + .ui.grid > .row > [class*="sixteen wide mobile"].column, + .ui.grid > .column.row > [class*="sixteen wide mobile"].column, + .ui.grid > [class*="sixteen wide mobile"].column, + .ui.column.grid > [class*="sixteen wide mobile"].column { + width: @sixteenWide !important; + } +} + +/* Tablet Sizing Combinations */ +@media only screen and (min-width: @tabletBreakpoint) and (max-width: @largestTabletScreen) { + .ui.grid > .row > [class*="one wide tablet"].column, + .ui.grid > .column.row > [class*="one wide tablet"].column, + .ui.grid > [class*="one wide tablet"].column, + .ui.column.grid > [class*="one wide tablet"].column { + width: @oneWide !important; + } + .ui.grid > .row > [class*="two wide tablet"].column, + .ui.grid > .column.row > [class*="two wide tablet"].column, + .ui.grid > [class*="two wide tablet"].column, + .ui.column.grid > [class*="two wide tablet"].column { + width: @twoWide !important; + } + .ui.grid > .row > [class*="three wide tablet"].column, + .ui.grid > .column.row > [class*="three wide tablet"].column, + .ui.grid > [class*="three wide tablet"].column, + .ui.column.grid > [class*="three wide tablet"].column { + width: @threeWide !important; + } + .ui.grid > .row > [class*="four wide tablet"].column, + .ui.grid > .column.row > [class*="four wide tablet"].column, + .ui.grid > [class*="four wide tablet"].column, + .ui.column.grid > [class*="four wide tablet"].column { + width: @fourWide !important; + } + .ui.grid > .row > [class*="five wide tablet"].column, + .ui.grid > .column.row > [class*="five wide tablet"].column, + .ui.grid > [class*="five wide tablet"].column, + .ui.column.grid > [class*="five wide tablet"].column { + width: @fiveWide !important; + } + .ui.grid > .row > [class*="six wide tablet"].column, + .ui.grid > .column.row > [class*="six wide tablet"].column, + .ui.grid > [class*="six wide tablet"].column, + .ui.column.grid > [class*="six wide tablet"].column { + width: @sixWide !important; + } + .ui.grid > .row > [class*="seven wide tablet"].column, + .ui.grid > .column.row > [class*="seven wide tablet"].column, + .ui.grid > [class*="seven wide tablet"].column, + .ui.column.grid > [class*="seven wide tablet"].column { + width: @sevenWide !important; + } + .ui.grid > .row > [class*="eight wide tablet"].column, + .ui.grid > .column.row > [class*="eight wide tablet"].column, + .ui.grid > [class*="eight wide tablet"].column, + .ui.column.grid > [class*="eight wide tablet"].column { + width: @eightWide !important; + } + .ui.grid > .row > [class*="nine wide tablet"].column, + .ui.grid > .column.row > [class*="nine wide tablet"].column, + .ui.grid > [class*="nine wide tablet"].column, + .ui.column.grid > [class*="nine wide tablet"].column { + width: @nineWide !important; + } + .ui.grid > .row > [class*="ten wide tablet"].column, + .ui.grid > .column.row > [class*="ten wide tablet"].column, + .ui.grid > [class*="ten wide tablet"].column, + .ui.column.grid > [class*="ten wide tablet"].column { + width: @tenWide !important; + } + .ui.grid > .row > [class*="eleven wide tablet"].column, + .ui.grid > .column.row > [class*="eleven wide tablet"].column, + .ui.grid > [class*="eleven wide tablet"].column, + .ui.column.grid > [class*="eleven wide tablet"].column { + width: @elevenWide !important; + } + .ui.grid > .row > [class*="twelve wide tablet"].column, + .ui.grid > .column.row > [class*="twelve wide tablet"].column, + .ui.grid > [class*="twelve wide tablet"].column, + .ui.column.grid > [class*="twelve wide tablet"].column { + width: @twelveWide !important; + } + .ui.grid > .row > [class*="thirteen wide tablet"].column, + .ui.grid > .column.row > [class*="thirteen wide tablet"].column, + .ui.grid > [class*="thirteen wide tablet"].column, + .ui.column.grid > [class*="thirteen wide tablet"].column { + width: @thirteenWide !important; + } + .ui.grid > .row > [class*="fourteen wide tablet"].column, + .ui.grid > .column.row > [class*="fourteen wide tablet"].column, + .ui.grid > [class*="fourteen wide tablet"].column, + .ui.column.grid > [class*="fourteen wide tablet"].column { + width: @fourteenWide !important; + } + .ui.grid > .row > [class*="fifteen wide tablet"].column, + .ui.grid > .column.row > [class*="fifteen wide tablet"].column, + .ui.grid > [class*="fifteen wide tablet"].column, + .ui.column.grid > [class*="fifteen wide tablet"].column { + width: @fifteenWide !important; + } + .ui.grid > .row > [class*="sixteen wide tablet"].column, + .ui.grid > .column.row > [class*="sixteen wide tablet"].column, + .ui.grid > [class*="sixteen wide tablet"].column, + .ui.column.grid > [class*="sixteen wide tablet"].column { + width: @sixteenWide !important; + } +} + +/* Computer/Desktop Sizing Combinations */ +@media only screen and (min-width: @computerBreakpoint) { + .ui.grid > .row > [class*="one wide computer"].column, + .ui.grid > .column.row > [class*="one wide computer"].column, + .ui.grid > [class*="one wide computer"].column, + .ui.column.grid > [class*="one wide computer"].column { + width: @oneWide !important; + } + .ui.grid > .row > [class*="two wide computer"].column, + .ui.grid > .column.row > [class*="two wide computer"].column, + .ui.grid > [class*="two wide computer"].column, + .ui.column.grid > [class*="two wide computer"].column { + width: @twoWide !important; + } + .ui.grid > .row > [class*="three wide computer"].column, + .ui.grid > .column.row > [class*="three wide computer"].column, + .ui.grid > [class*="three wide computer"].column, + .ui.column.grid > [class*="three wide computer"].column { + width: @threeWide !important; + } + .ui.grid > .row > [class*="four wide computer"].column, + .ui.grid > .column.row > [class*="four wide computer"].column, + .ui.grid > [class*="four wide computer"].column, + .ui.column.grid > [class*="four wide computer"].column { + width: @fourWide !important; + } + .ui.grid > .row > [class*="five wide computer"].column, + .ui.grid > .column.row > [class*="five wide computer"].column, + .ui.grid > [class*="five wide computer"].column, + .ui.column.grid > [class*="five wide computer"].column { + width: @fiveWide !important; + } + .ui.grid > .row > [class*="six wide computer"].column, + .ui.grid > .column.row > [class*="six wide computer"].column, + .ui.grid > [class*="six wide computer"].column, + .ui.column.grid > [class*="six wide computer"].column { + width: @sixWide !important; + } + .ui.grid > .row > [class*="seven wide computer"].column, + .ui.grid > .column.row > [class*="seven wide computer"].column, + .ui.grid > [class*="seven wide computer"].column, + .ui.column.grid > [class*="seven wide computer"].column { + width: @sevenWide !important; + } + .ui.grid > .row > [class*="eight wide computer"].column, + .ui.grid > .column.row > [class*="eight wide computer"].column, + .ui.grid > [class*="eight wide computer"].column, + .ui.column.grid > [class*="eight wide computer"].column { + width: @eightWide !important; + } + .ui.grid > .row > [class*="nine wide computer"].column, + .ui.grid > .column.row > [class*="nine wide computer"].column, + .ui.grid > [class*="nine wide computer"].column, + .ui.column.grid > [class*="nine wide computer"].column { + width: @nineWide !important; + } + .ui.grid > .row > [class*="ten wide computer"].column, + .ui.grid > .column.row > [class*="ten wide computer"].column, + .ui.grid > [class*="ten wide computer"].column, + .ui.column.grid > [class*="ten wide computer"].column { + width: @tenWide !important; + } + .ui.grid > .row > [class*="eleven wide computer"].column, + .ui.grid > .column.row > [class*="eleven wide computer"].column, + .ui.grid > [class*="eleven wide computer"].column, + .ui.column.grid > [class*="eleven wide computer"].column { + width: @elevenWide !important; + } + .ui.grid > .row > [class*="twelve wide computer"].column, + .ui.grid > .column.row > [class*="twelve wide computer"].column, + .ui.grid > [class*="twelve wide computer"].column, + .ui.column.grid > [class*="twelve wide computer"].column { + width: @twelveWide !important; + } + .ui.grid > .row > [class*="thirteen wide computer"].column, + .ui.grid > .column.row > [class*="thirteen wide computer"].column, + .ui.grid > [class*="thirteen wide computer"].column, + .ui.column.grid > [class*="thirteen wide computer"].column { + width: @thirteenWide !important; + } + .ui.grid > .row > [class*="fourteen wide computer"].column, + .ui.grid > .column.row > [class*="fourteen wide computer"].column, + .ui.grid > [class*="fourteen wide computer"].column, + .ui.column.grid > [class*="fourteen wide computer"].column { + width: @fourteenWide !important; + } + .ui.grid > .row > [class*="fifteen wide computer"].column, + .ui.grid > .column.row > [class*="fifteen wide computer"].column, + .ui.grid > [class*="fifteen wide computer"].column, + .ui.column.grid > [class*="fifteen wide computer"].column { + width: @fifteenWide !important; + } + .ui.grid > .row > [class*="sixteen wide computer"].column, + .ui.grid > .column.row > [class*="sixteen wide computer"].column, + .ui.grid > [class*="sixteen wide computer"].column, + .ui.column.grid > [class*="sixteen wide computer"].column { + width: @sixteenWide !important; + } +} + +/* Large Monitor Sizing Combinations */ +@media only screen and (min-width: @largeMonitorBreakpoint) and (max-width: @largestLargeMonitor){ + .ui.grid > .row > [class*="one wide large screen"].column, + .ui.grid > .column.row > [class*="one wide large screen"].column, + .ui.grid > [class*="one wide large screen"].column, + .ui.column.grid > [class*="one wide large screen"].column { + width: @oneWide !important; + } + .ui.grid > .row > [class*="two wide large screen"].column, + .ui.grid > .column.row > [class*="two wide large screen"].column, + .ui.grid > [class*="two wide large screen"].column, + .ui.column.grid > [class*="two wide large screen"].column { + width: @twoWide !important; + } + .ui.grid > .row > [class*="three wide large screen"].column, + .ui.grid > .column.row > [class*="three wide large screen"].column, + .ui.grid > [class*="three wide large screen"].column, + .ui.column.grid > [class*="three wide large screen"].column { + width: @threeWide !important; + } + .ui.grid > .row > [class*="four wide large screen"].column, + .ui.grid > .column.row > [class*="four wide large screen"].column, + .ui.grid > [class*="four wide large screen"].column, + .ui.column.grid > [class*="four wide large screen"].column { + width: @fourWide !important; + } + .ui.grid > .row > [class*="five wide large screen"].column, + .ui.grid > .column.row > [class*="five wide large screen"].column, + .ui.grid > [class*="five wide large screen"].column, + .ui.column.grid > [class*="five wide large screen"].column { + width: @fiveWide !important; + } + .ui.grid > .row > [class*="six wide large screen"].column, + .ui.grid > .column.row > [class*="six wide large screen"].column, + .ui.grid > [class*="six wide large screen"].column, + .ui.column.grid > [class*="six wide large screen"].column { + width: @sixWide !important; + } + .ui.grid > .row > [class*="seven wide large screen"].column, + .ui.grid > .column.row > [class*="seven wide large screen"].column, + .ui.grid > [class*="seven wide large screen"].column, + .ui.column.grid > [class*="seven wide large screen"].column { + width: @sevenWide !important; + } + .ui.grid > .row > [class*="eight wide large screen"].column, + .ui.grid > .column.row > [class*="eight wide large screen"].column, + .ui.grid > [class*="eight wide large screen"].column, + .ui.column.grid > [class*="eight wide large screen"].column { + width: @eightWide !important; + } + .ui.grid > .row > [class*="nine wide large screen"].column, + .ui.grid > .column.row > [class*="nine wide large screen"].column, + .ui.grid > [class*="nine wide large screen"].column, + .ui.column.grid > [class*="nine wide large screen"].column { + width: @nineWide !important; + } + .ui.grid > .row > [class*="ten wide large screen"].column, + .ui.grid > .column.row > [class*="ten wide large screen"].column, + .ui.grid > [class*="ten wide large screen"].column, + .ui.column.grid > [class*="ten wide large screen"].column { + width: @tenWide !important; + } + .ui.grid > .row > [class*="eleven wide large screen"].column, + .ui.grid > .column.row > [class*="eleven wide large screen"].column, + .ui.grid > [class*="eleven wide large screen"].column, + .ui.column.grid > [class*="eleven wide large screen"].column { + width: @elevenWide !important; + } + .ui.grid > .row > [class*="twelve wide large screen"].column, + .ui.grid > .column.row > [class*="twelve wide large screen"].column, + .ui.grid > [class*="twelve wide large screen"].column, + .ui.column.grid > [class*="twelve wide large screen"].column { + width: @twelveWide !important; + } + .ui.grid > .row > [class*="thirteen wide large screen"].column, + .ui.grid > .column.row > [class*="thirteen wide large screen"].column, + .ui.grid > [class*="thirteen wide large screen"].column, + .ui.column.grid > [class*="thirteen wide large screen"].column { + width: @thirteenWide !important; + } + .ui.grid > .row > [class*="fourteen wide large screen"].column, + .ui.grid > .column.row > [class*="fourteen wide large screen"].column, + .ui.grid > [class*="fourteen wide large screen"].column, + .ui.column.grid > [class*="fourteen wide large screen"].column { + width: @fourteenWide !important; + } + .ui.grid > .row > [class*="fifteen wide large screen"].column, + .ui.grid > .column.row > [class*="fifteen wide large screen"].column, + .ui.grid > [class*="fifteen wide large screen"].column, + .ui.column.grid > [class*="fifteen wide large screen"].column { + width: @fifteenWide !important; + } + .ui.grid > .row > [class*="sixteen wide large screen"].column, + .ui.grid > .column.row > [class*="sixteen wide large screen"].column, + .ui.grid > [class*="sixteen wide large screen"].column, + .ui.column.grid > [class*="sixteen wide large screen"].column { + width: @sixteenWide !important; + } +} + +/* Widescreen Sizing Combinations */ +@media only screen and (min-width: @widescreenMonitorBreakpoint) { + .ui.grid > .row > [class*="one wide widescreen"].column, + .ui.grid > .column.row > [class*="one wide widescreen"].column, + .ui.grid > [class*="one wide widescreen"].column, + .ui.column.grid > [class*="one wide widescreen"].column { + width: @oneWide !important; + } + .ui.grid > .row > [class*="two wide widescreen"].column, + .ui.grid > .column.row > [class*="two wide widescreen"].column, + .ui.grid > [class*="two wide widescreen"].column, + .ui.column.grid > [class*="two wide widescreen"].column { + width: @twoWide !important; + } + .ui.grid > .row > [class*="three wide widescreen"].column, + .ui.grid > .column.row > [class*="three wide widescreen"].column, + .ui.grid > [class*="three wide widescreen"].column, + .ui.column.grid > [class*="three wide widescreen"].column { + width: @threeWide !important; + } + .ui.grid > .row > [class*="four wide widescreen"].column, + .ui.grid > .column.row > [class*="four wide widescreen"].column, + .ui.grid > [class*="four wide widescreen"].column, + .ui.column.grid > [class*="four wide widescreen"].column { + width: @fourWide !important; + } + .ui.grid > .row > [class*="five wide widescreen"].column, + .ui.grid > .column.row > [class*="five wide widescreen"].column, + .ui.grid > [class*="five wide widescreen"].column, + .ui.column.grid > [class*="five wide widescreen"].column { + width: @fiveWide !important; + } + .ui.grid > .row > [class*="six wide widescreen"].column, + .ui.grid > .column.row > [class*="six wide widescreen"].column, + .ui.grid > [class*="six wide widescreen"].column, + .ui.column.grid > [class*="six wide widescreen"].column { + width: @sixWide !important; + } + .ui.grid > .row > [class*="seven wide widescreen"].column, + .ui.grid > .column.row > [class*="seven wide widescreen"].column, + .ui.grid > [class*="seven wide widescreen"].column, + .ui.column.grid > [class*="seven wide widescreen"].column { + width: @sevenWide !important; + } + .ui.grid > .row > [class*="eight wide widescreen"].column, + .ui.grid > .column.row > [class*="eight wide widescreen"].column, + .ui.grid > [class*="eight wide widescreen"].column, + .ui.column.grid > [class*="eight wide widescreen"].column { + width: @eightWide !important; + } + .ui.grid > .row > [class*="nine wide widescreen"].column, + .ui.grid > .column.row > [class*="nine wide widescreen"].column, + .ui.grid > [class*="nine wide widescreen"].column, + .ui.column.grid > [class*="nine wide widescreen"].column { + width: @nineWide !important; + } + .ui.grid > .row > [class*="ten wide widescreen"].column, + .ui.grid > .column.row > [class*="ten wide widescreen"].column, + .ui.grid > [class*="ten wide widescreen"].column, + .ui.column.grid > [class*="ten wide widescreen"].column { + width: @tenWide !important; + } + .ui.grid > .row > [class*="eleven wide widescreen"].column, + .ui.grid > .column.row > [class*="eleven wide widescreen"].column, + .ui.grid > [class*="eleven wide widescreen"].column, + .ui.column.grid > [class*="eleven wide widescreen"].column { + width: @elevenWide !important; + } + .ui.grid > .row > [class*="twelve wide widescreen"].column, + .ui.grid > .column.row > [class*="twelve wide widescreen"].column, + .ui.grid > [class*="twelve wide widescreen"].column, + .ui.column.grid > [class*="twelve wide widescreen"].column { + width: @twelveWide !important; + } + .ui.grid > .row > [class*="thirteen wide widescreen"].column, + .ui.grid > .column.row > [class*="thirteen wide widescreen"].column, + .ui.grid > [class*="thirteen wide widescreen"].column, + .ui.column.grid > [class*="thirteen wide widescreen"].column { + width: @thirteenWide !important; + } + .ui.grid > .row > [class*="fourteen wide widescreen"].column, + .ui.grid > .column.row > [class*="fourteen wide widescreen"].column, + .ui.grid > [class*="fourteen wide widescreen"].column, + .ui.column.grid > [class*="fourteen wide widescreen"].column { + width: @fourteenWide !important; + } + .ui.grid > .row > [class*="fifteen wide widescreen"].column, + .ui.grid > .column.row > [class*="fifteen wide widescreen"].column, + .ui.grid > [class*="fifteen wide widescreen"].column, + .ui.column.grid > [class*="fifteen wide widescreen"].column { + width: @fifteenWide !important; + } + .ui.grid > .row > [class*="sixteen wide widescreen"].column, + .ui.grid > .column.row > [class*="sixteen wide widescreen"].column, + .ui.grid > [class*="sixteen wide widescreen"].column, + .ui.column.grid > [class*="sixteen wide widescreen"].column { + width: @sixteenWide !important; + } +} + +& when (@variationGridCentered) { + /*---------------------- + Centered + -----------------------*/ + + .ui.centered.grid, + .ui.centered.grid > .row, + .ui.grid > .centered.row { + text-align: center; + justify-content: center; + } + .ui.centered.grid > .column:not(.aligned):not(.justified):not(.row), + .ui.centered.grid > .row > .column:not(.aligned):not(.justified), + .ui.grid .centered.row > .column:not(.aligned):not(.justified) { + text-align: left; + } + + .ui.grid > .centered.column, + .ui.grid > .row > .centered.column { + display: block; + margin-left: auto; + margin-right: auto; + } +} + +& when (@variationGridRelaxed) { + /*---------------------- + Relaxed + -----------------------*/ + + .ui.relaxed.grid > .column:not(.row), + .ui.relaxed.grid > .row > .column, + .ui.grid > .relaxed.row > .column { + padding-left: (@relaxedGutterWidth / 2); + padding-right: (@relaxedGutterWidth / 2); + } + + .ui[class*="very relaxed"].grid > .column:not(.row), + .ui[class*="very relaxed"].grid > .row > .column, + .ui.grid > [class*="very relaxed"].row > .column { + padding-left: (@veryRelaxedGutterWidth / 2); + padding-right: (@veryRelaxedGutterWidth / 2); + } + + /* Coupling with UI Divider */ + .ui.relaxed.grid .row + .ui.divider, + .ui.grid .relaxed.row + .ui.divider { + margin-left: (@relaxedGutterWidth / 2); + margin-right: (@relaxedGutterWidth / 2); + } + .ui[class*="very relaxed"].grid .row + .ui.divider, + .ui.grid [class*="very relaxed"].row + .ui.divider { + margin-left: (@veryRelaxedGutterWidth / 2); + margin-right: (@veryRelaxedGutterWidth / 2); + } +} + +& when (@variationGridPadded) { + /*---------------------- + Padded + -----------------------*/ + + .ui.padded.grid:not(.vertically):not(.horizontally) { + margin: 0 !important; + } + [class*="horizontally padded"].ui.grid { + margin-left: 0 !important; + margin-right: 0 !important; + } + [class*="vertically padded"].ui.grid { + margin-top: 0 !important; + margin-bottom: 0 !important; + } +} + +& when (@variationGridFloated) { + /*---------------------- + "Floated" + -----------------------*/ + + .ui.grid [class*="left floated"].column { + margin-right: auto; + } + .ui.grid [class*="right floated"].column { + margin-left: auto; + } +} + +& when (@variationGridDivided) { + /*---------------------- + Divided + -----------------------*/ + + .ui.divided.grid:not([class*="vertically divided"]) > .column:not(.row), + .ui.divided.grid:not([class*="vertically divided"]) > .row > .column { + box-shadow: @dividedBorder; + } + + /* Swap from padding to margin on columns to have dividers align */ + .ui[class*="vertically divided"].grid > .column:not(.row), + .ui[class*="vertically divided"].grid > .row > .column { + margin-top: (@rowSpacing / 2); + margin-bottom: (@rowSpacing / 2); + padding-top: 0; + padding-bottom: 0; + } + .ui[class*="vertically divided"].grid > .row { + margin-top: 0; + margin-bottom: 0; + } + + + + /* No divider on first column on row */ + .ui.divided.grid:not([class*="vertically divided"]) > .column:first-child, + .ui.divided.grid:not([class*="vertically divided"]) > .row > .column:first-child { + box-shadow: none; + } + + /* No space on top of first row */ + .ui[class*="vertically divided"].grid > .row:first-child > .column { + margin-top: 0; + } + + + /* Divided Row */ + .ui.grid > .divided.row > .column { + box-shadow: @dividedBorder; + } + .ui.grid > .divided.row > .column:first-child { + box-shadow: none; + } + + /* Vertically Divided */ + .ui[class*="vertically divided"].grid > .row { + position: relative; + } + .ui[class*="vertically divided"].grid > .row:before { + position: absolute; + content: ""; + top: 0; + left: 0; + + width: e(%("calc(100%% - %d)", @gutterWidth)); + height: 1px; + + margin: 0 (@gutterWidth / 2); + box-shadow: @verticallyDividedBorder; + } + + & when (@variationGridPadded) { + /* Padded Horizontally Divided */ + [class*="horizontally padded"].ui.divided.grid, + .ui.padded.divided.grid:not(.vertically):not(.horizontally) { + width: 100%; + } + } + /* First Row Vertically Divided */ + .ui[class*="vertically divided"].grid > .row:first-child:before { + box-shadow: none; + } + & when (@variationGridInverted) { + /* Inverted Divided */ + .ui.inverted.divided.grid:not([class*="vertically divided"]) > .column:not(.row), + .ui.inverted.divided.grid:not([class*="vertically divided"]) > .row > .column { + box-shadow: @dividedInvertedBorder; + } + .ui.inverted.divided.grid:not([class*="vertically divided"]) > .column:not(.row):first-child, + .ui.inverted.divided.grid:not([class*="vertically divided"]) > .row > .column:first-child { + box-shadow: none; + } + .ui.inverted[class*="vertically divided"].grid > .row:before { + box-shadow: @verticallyDividedInvertedBorder; + } + } + & when (@variationGridRelaxed) { + /* Relaxed */ + .ui.relaxed[class*="vertically divided"].grid > .row:before { + margin-left: (@relaxedGutterWidth / 2); + margin-right: (@relaxedGutterWidth / 2); + width: e(%("calc(100%% - %d)", @relaxedGutterWidth)); + } + .ui[class*="very relaxed"][class*="vertically divided"].grid > .row:before { + margin-left: (@veryRelaxedGutterWidth / 2); + margin-right: (@veryRelaxedGutterWidth / 2); + width: e(%("calc(100%% - %d)", @veryRelaxedGutterWidth)); + } + } +} + +& when (@variationGridCelled) { + /*---------------------- + Celled + -----------------------*/ + + .ui.celled.grid { + width: 100%; + margin: @celledMargin; + box-shadow: @celledGridDivider; + } + + .ui.celled.grid > .row { + width: 100% !important; + margin: 0; + padding: 0; + box-shadow: @celledRowDivider; + } + .ui.celled.grid > .column:not(.row), + .ui.celled.grid > .row > .column { + box-shadow: @celledColumnDivider; + } + + .ui.celled.grid > .column:first-child, + .ui.celled.grid > .row > .column:first-child { + box-shadow: none; + } + + .ui.celled.grid > .column:not(.row), + .ui.celled.grid > .row > .column { + padding: @celledPadding; + } + & when (@variationGridRelaxed) { + .ui.relaxed.celled.grid > .column:not(.row), + .ui.relaxed.celled.grid > .row > .column { + padding: @celledRelaxedPadding; + } + .ui[class*="very relaxed"].celled.grid > .column:not(.row), + .ui[class*="very relaxed"].celled.grid > .row > .column { + padding: @celledVeryRelaxedPadding; + } + } + /* Internally Celled */ + .ui[class*="internally celled"].grid { + box-shadow: none; + margin: 0; + } + .ui[class*="internally celled"].grid > .row:first-child { + box-shadow: none; + } + .ui[class*="internally celled"].grid > .row > .column:first-child { + box-shadow: none; + } +} + +& when (@variationGridAligned) { + /*---------------------- + Vertically Aligned + -----------------------*/ + + /* Top Aligned */ + .ui[class*="top aligned"].grid > .column:not(.row), + .ui[class*="top aligned"].grid > .row > .column, + .ui.grid > [class*="top aligned"].row > .column, + .ui.grid > [class*="top aligned"].column:not(.row), + .ui.grid > .row > [class*="top aligned"].column { + flex-direction: column; + vertical-align: top; + align-self: flex-start !important; + } + + /* Middle Aligned */ + .ui[class*="middle aligned"].grid > .column:not(.row), + .ui[class*="middle aligned"].grid > .row > .column, + .ui.grid > [class*="middle aligned"].row > .column, + .ui.grid > [class*="middle aligned"].column:not(.row), + .ui.grid > .row > [class*="middle aligned"].column { + flex-direction: column; + vertical-align: middle; + align-self: center !important; + } + + /* Bottom Aligned */ + .ui[class*="bottom aligned"].grid > .column:not(.row), + .ui[class*="bottom aligned"].grid > .row > .column, + .ui.grid > [class*="bottom aligned"].row > .column, + .ui.grid > [class*="bottom aligned"].column:not(.row), + .ui.grid > .row > [class*="bottom aligned"].column { + flex-direction: column; + vertical-align: bottom; + align-self: flex-end !important; + } +} + +& when (@variationGridStretched) { + /* Stretched */ + .ui.stretched.grid > .row > .column, + .ui.stretched.grid > .column, + .ui.grid > .stretched.row > .column, + .ui.grid > .stretched.column:not(.row), + .ui.grid > .row > .stretched.column { + display: inline-flex !important; + align-self: stretch; + flex-direction: column; + } + + .ui.stretched.grid > .row > .column > *, + .ui.stretched.grid > .column > *, + .ui.grid > .stretched.row > .column > *, + .ui.grid > .stretched.column:not(.row) > *, + .ui.grid > .row > .stretched.column > * { + flex-grow: 1; + } +} + +& when (@variationGridAligned) { + /*---------------------- + Horizontally Centered + -----------------------*/ + + /* Left Aligned */ + + .ui[class*="left aligned"].grid > .column, + .ui[class*="left aligned"].grid > .row > .column, + .ui.grid > [class*="left aligned"].row > .column, + .ui.grid > [class*="left aligned"].column.column, + .ui.grid > .row > [class*="left aligned"].column.column { + text-align: left; + align-self: inherit; + } + + /* Center Aligned */ + + .ui[class*="center aligned"].grid > .column, + .ui[class*="center aligned"].grid > .row > .column, + .ui.grid > [class*="center aligned"].row > .column, + .ui.grid > [class*="center aligned"].column.column, + .ui.grid > .row > [class*="center aligned"].column.column { + text-align: center; + align-self: inherit; + } + + .ui[class*="center aligned"].grid { + justify-content: center; + } + + /* Right Aligned */ + + .ui[class*="right aligned"].grid > .column, + .ui[class*="right aligned"].grid > .row > .column, + .ui.grid > [class*="right aligned"].row > .column, + .ui.grid > [class*="right aligned"].column.column, + .ui.grid > .row > [class*="right aligned"].column.column { + text-align: right; + align-self: inherit; + } +} + +& when (@variationGridJustified) { + /* Justified */ + .ui.justified.grid > .column, + .ui.justified.grid > .row > .column, + .ui.grid > .justified.row > .column, + .ui.grid > .justified.column.column, + .ui.grid > .row > .justified.column.column { + text-align: justify; + hyphens: auto; + } +} + +/*---------------------- + Colored +-----------------------*/ + +each(@colors, { + @color: replace(@key, '@', ''); + @c: @colors[@@color][color]; + + .ui.grid > .@{color}.row, + .ui.grid > .@{color}.column, + .ui.grid > .row > .@{color}.column { + background-color: @c; + color: @white; + } +}) + + +/*---------------------- + Equal Width +-----------------------*/ + +.ui[class*="equal width"].grid > .column:not(.row), +.ui[class*="equal width"].grid > .row > .column, +.ui.grid > [class*="equal width"].row > .column { + display: inline-block; + flex-grow: 1; +} +.ui[class*="equal width"].grid > .wide.column, +.ui[class*="equal width"].grid > .row > .wide.column, +.ui.grid > [class*="equal width"].row > .wide.column { + flex-grow: 0; +} + +& when (@variationGridReversed) { + /*---------------------- + Reverse + -----------------------*/ + + + /* Mobile */ + @media only screen and (max-width: @largestMobileScreen) { + .ui[class*="mobile reversed"].grid, + .ui[class*="mobile reversed"].grid > .row, + .ui.grid > [class*="mobile reversed"].row { + flex-direction: row-reverse; + } + .ui[class*="mobile vertically reversed"].grid, + .ui.stackable[class*="mobile reversed"] { + flex-direction: column-reverse; + } + & when (@variationGridDivided) { + /* Divided Reversed */ + .ui[class*="mobile reversed"].divided.grid:not([class*="vertically divided"]) > .column:first-child, + .ui[class*="mobile reversed"].divided.grid:not([class*="vertically divided"]) > .row > .column:first-child { + box-shadow: @dividedBorder; + } + .ui[class*="mobile reversed"].divided.grid:not([class*="vertically divided"]) > .column:last-child, + .ui[class*="mobile reversed"].divided.grid:not([class*="vertically divided"]) > .row > .column:last-child { + box-shadow: none; + } + /* Vertically Divided Reversed */ + .ui.grid[class*="vertically divided"][class*="mobile vertically reversed"] > .row:first-child:before { + box-shadow: @verticallyDividedBorder; + } + .ui.grid[class*="vertically divided"][class*="mobile vertically reversed"] > .row:last-child:before { + box-shadow: none; + } + } + & when (@variationGridCelled) { + /* Celled Reversed */ + .ui[class*="mobile reversed"].celled.grid > .row > .column:first-child { + box-shadow: @celledColumnDivider; + } + .ui[class*="mobile reversed"].celled.grid > .row > .column:last-child { + box-shadow: none; + } + } + } + + /* Tablet */ + @media only screen and (min-width: @tabletBreakpoint) and (max-width: @largestTabletScreen) { + .ui[class*="tablet reversed"].grid, + .ui[class*="tablet reversed"].grid > .row, + .ui.grid > [class*="tablet reversed"].row { + flex-direction: row-reverse; + } + .ui[class*="tablet vertically reversed"].grid { + flex-direction: column-reverse; + } + & when (@variationGridDivided) { + /* Divided Reversed */ + .ui[class*="tablet reversed"].divided.grid:not([class*="vertically divided"]) > .column:first-child, + .ui[class*="tablet reversed"].divided.grid:not([class*="vertically divided"]) > .row > .column:first-child { + box-shadow: @dividedBorder; + } + .ui[class*="tablet reversed"].divided.grid:not([class*="vertically divided"]) > .column:last-child, + .ui[class*="tablet reversed"].divided.grid:not([class*="vertically divided"]) > .row > .column:last-child { + box-shadow: none; + } + /* Vertically Divided Reversed */ + .ui.grid[class*="vertically divided"][class*="tablet vertically reversed"] > .row:first-child:before { + box-shadow: @verticallyDividedBorder; + } + .ui.grid[class*="vertically divided"][class*="tablet vertically reversed"] > .row:last-child:before { + box-shadow: none; + } + } + & when (@variationGridCelled) { + /* Celled Reversed */ + .ui[class*="tablet reversed"].celled.grid > .row > .column:first-child { + box-shadow: @celledColumnDivider; + } + .ui[class*="tablet reversed"].celled.grid > .row > .column:last-child { + box-shadow: none; + } + } + } + + /* Computer */ + @media only screen and (min-width: @computerBreakpoint) { + .ui[class*="computer reversed"].grid, + .ui[class*="computer reversed"].grid > .row, + .ui.grid > [class*="computer reversed"].row { + flex-direction: row-reverse; + } + .ui[class*="computer vertically reversed"].grid { + flex-direction: column-reverse; + } + & when (@variationGridDivided) { + /* Divided Reversed */ + .ui[class*="computer reversed"].divided.grid:not([class*="vertically divided"]) > .column:first-child, + .ui[class*="computer reversed"].divided.grid:not([class*="vertically divided"]) > .row > .column:first-child { + box-shadow: @dividedBorder; + } + .ui[class*="computer reversed"].divided.grid:not([class*="vertically divided"]) > .column:last-child, + .ui[class*="computer reversed"].divided.grid:not([class*="vertically divided"]) > .row > .column:last-child { + box-shadow: none; + } + /* Vertically Divided Reversed */ + .ui.grid[class*="vertically divided"][class*="computer vertically reversed"] > .row:first-child:before { + box-shadow: @verticallyDividedBorder; + } + .ui.grid[class*="vertically divided"][class*="computer vertically reversed"] > .row:last-child:before { + box-shadow: none; + } + } + & when (@variationGridCelled) { + /* Celled Reversed */ + .ui[class*="computer reversed"].celled.grid > .row > .column:first-child { + box-shadow: @celledColumnDivider; + } + .ui[class*="computer reversed"].celled.grid > .row > .column:last-child { + box-shadow: none; + } + } + } +} + +& when (@variationGridDoubling) { + /*------------------- + Doubling + --------------------*/ + + /* Tablet Only */ + @media only screen and (min-width: @tabletBreakpoint) and (max-width: @largestTabletScreen) { + .ui.doubling.grid { + width: auto; + } + .ui.grid > .doubling.row, + .ui.doubling.grid > .row { + margin: 0 !important; + padding: 0 !important; + } + .ui.grid > .doubling.row > .column, + .ui.doubling.grid > .row > .column { + display: inline-block !important; + padding-top: (@rowSpacing / 2) !important; + padding-bottom: (@rowSpacing / 2) !important; + box-shadow: none !important; + margin: 0; + } + .ui[class*="two column"].doubling.grid > .row > .column, + .ui[class*="two column"].doubling.grid > .column:not(.row), + .ui.grid > [class*="two column"].doubling.row.row > .column { + width: @oneColumn !important; + } + .ui[class*="three column"].doubling.grid > .row > .column, + .ui[class*="three column"].doubling.grid > .column:not(.row), + .ui.grid > [class*="three column"].doubling.row.row > .column { + width: @twoColumn !important; + } + .ui[class*="four column"].doubling.grid > .row > .column, + .ui[class*="four column"].doubling.grid > .column:not(.row), + .ui.grid > [class*="four column"].doubling.row.row > .column { + width: @twoColumn !important; + } + .ui[class*="five column"].doubling.grid > .row > .column, + .ui[class*="five column"].doubling.grid > .column:not(.row), + .ui.grid > [class*="five column"].doubling.row.row > .column { + width: @threeColumn !important; + } + .ui[class*="six column"].doubling.grid > .row > .column, + .ui[class*="six column"].doubling.grid > .column:not(.row), + .ui.grid > [class*="six column"].doubling.row.row > .column { + width: @threeColumn !important; + } + .ui[class*="seven column"].doubling.grid > .row > .column, + .ui[class*="seven column"].doubling.grid > .column:not(.row), + .ui.grid > [class*="seven column"].doubling.row.row > .column { + width: @threeColumn !important; + } + .ui[class*="eight column"].doubling.grid > .row > .column, + .ui[class*="eight column"].doubling.grid > .column:not(.row), + .ui.grid > [class*="eight column"].doubling.row.row > .column { + width: @fourColumn !important; + } + .ui[class*="nine column"].doubling.grid > .row > .column, + .ui[class*="nine column"].doubling.grid > .column:not(.row), + .ui.grid > [class*="nine column"].doubling.row.row > .column { + width: @fourColumn !important; + } + .ui[class*="ten column"].doubling.grid > .row > .column, + .ui[class*="ten column"].doubling.grid > .column:not(.row), + .ui.grid > [class*="ten column"].doubling.row.row > .column { + width: @fiveColumn !important; + } + .ui[class*="eleven column"].doubling.grid > .row > .column, + .ui[class*="eleven column"].doubling.grid > .column:not(.row), + .ui.grid > [class*="eleven column"].doubling.row.row > .column { + width: @fiveColumn !important; + } + .ui[class*="twelve column"].doubling.grid > .row > .column, + .ui[class*="twelve column"].doubling.grid > .column:not(.row), + .ui.grid > [class*="twelve column"].doubling.row.row > .column { + width: @sixColumn !important; + } + .ui[class*="thirteen column"].doubling.grid > .row > .column, + .ui[class*="thirteen column"].doubling.grid > .column:not(.row), + .ui.grid > [class*="thirteen column"].doubling.row.row > .column { + width: @sixColumn !important; + } + .ui[class*="fourteen column"].doubling.grid > .row > .column, + .ui[class*="fourteen column"].doubling.grid > .column:not(.row), + .ui.grid > [class*="fourteen column"].doubling.row.row > .column { + width: @sevenColumn !important; + } + .ui[class*="fifteen column"].doubling.grid > .row > .column, + .ui[class*="fifteen column"].doubling.grid > .column:not(.row), + .ui.grid > [class*="fifteen column"].doubling.row.row > .column { + width: @sevenColumn !important; + } + .ui[class*="sixteen column"].doubling.grid > .row > .column, + .ui[class*="sixteen column"].doubling.grid > .column:not(.row), + .ui.grid > [class*="sixteen column"].doubling.row.row > .column { + width: @eightColumn !important; + } + } + + /* Mobile Only */ + @media only screen and (max-width: @largestMobileScreen) { + .ui.grid > .doubling.row, + .ui.doubling.grid > .row { + margin: 0 !important; + padding: 0 !important; + } + .ui.grid > .doubling.row > .column, + .ui.doubling.grid > .row > .column { + padding-top: (@rowSpacing / 2) !important; + padding-bottom: (@rowSpacing / 2) !important; + margin: 0 !important; + box-shadow: none !important; + } + .ui[class*="two column"].doubling:not(.stackable).grid > .row > .column, + .ui[class*="two column"].doubling:not(.stackable).grid > .column:not(.row), + .ui.grid > [class*="two column"].doubling:not(.stackable).row.row > .column { + width: @oneColumn !important; + } + .ui[class*="three column"].doubling:not(.stackable).grid > .row > .column, + .ui[class*="three column"].doubling:not(.stackable).grid > .column:not(.row), + .ui.grid > [class*="three column"].doubling:not(.stackable).row.row > .column { + width: @twoColumn !important; + } + .ui[class*="four column"].doubling:not(.stackable).grid > .row > .column, + .ui[class*="four column"].doubling:not(.stackable).grid > .column:not(.row), + .ui.grid > [class*="four column"].doubling:not(.stackable).row.row > .column { + width: @twoColumn !important; + } + .ui[class*="five column"].doubling:not(.stackable).grid > .row > .column, + .ui[class*="five column"].doubling:not(.stackable).grid > .column:not(.row), + .ui.grid > [class*="five column"].doubling:not(.stackable).row.row > .column { + width: @twoColumn !important; + } + .ui[class*="six column"].doubling:not(.stackable).grid > .row > .column, + .ui[class*="six column"].doubling:not(.stackable).grid > .column:not(.row), + .ui.grid > [class*="six column"].doubling:not(.stackable).row.row > .column { + width: @twoColumn !important; + } + .ui[class*="seven column"].doubling:not(.stackable).grid > .row > .column, + .ui[class*="seven column"].doubling:not(.stackable).grid > .column:not(.row), + .ui.grid > [class*="seven column"].doubling:not(.stackable).row.row > .column { + width: @twoColumn !important; + } + .ui[class*="eight column"].doubling:not(.stackable).grid > .row > .column, + .ui[class*="eight column"].doubling:not(.stackable).grid > .column:not(.row), + .ui.grid > [class*="eight column"].doubling:not(.stackable).row.row > .column { + width: @twoColumn !important; + } + .ui[class*="nine column"].doubling:not(.stackable).grid > .row > .column, + .ui[class*="nine column"].doubling:not(.stackable).grid > .column:not(.row), + .ui.grid > [class*="nine column"].doubling:not(.stackable).row.row > .column { + width: @threeColumn !important; + } + .ui[class*="ten column"].doubling:not(.stackable).grid > .row > .column, + .ui[class*="ten column"].doubling:not(.stackable).grid > .column:not(.row), + .ui.grid > [class*="ten column"].doubling:not(.stackable).row.row > .column { + width: @threeColumn !important; + } + .ui[class*="eleven column"].doubling:not(.stackable).grid > .row > .column, + .ui[class*="eleven column"].doubling:not(.stackable).grid > .column:not(.row), + .ui.grid > [class*="eleven column"].doubling:not(.stackable).row.row > .column { + width: @threeColumn !important; + } + .ui[class*="twelve column"].doubling:not(.stackable).grid > .row > .column, + .ui[class*="twelve column"].doubling:not(.stackable).grid > .column:not(.row), + .ui.grid > [class*="twelve column"].doubling:not(.stackable).row.row > .column { + width: @threeColumn !important; + } + .ui[class*="thirteen column"].doubling:not(.stackable).grid > .row > .column, + .ui[class*="thirteen column"].doubling:not(.stackable).grid > .column:not(.row), + .ui.grid > [class*="thirteen column"].doubling:not(.stackable).row.row > .column { + width: @threeColumn !important; + } + .ui[class*="fourteen column"].doubling:not(.stackable).grid > .row > .column, + .ui[class*="fourteen column"].doubling:not(.stackable).grid > .column:not(.row), + .ui.grid > [class*="fourteen column"].doubling:not(.stackable).row.row > .column { + width: @fourColumn !important; + } + .ui[class*="fifteen column"].doubling:not(.stackable).grid > .row > .column, + .ui[class*="fifteen column"].doubling:not(.stackable).grid > .column:not(.row), + .ui.grid > [class*="fifteen column"].doubling:not(.stackable).row.row > .column { + width: @fourColumn !important; + } + .ui[class*="sixteen column"].doubling:not(.stackable).grid > .row > .column, + .ui[class*="sixteen column"].doubling:not(.stackable).grid > .column:not(.row), + .ui.grid > [class*="sixteen column"].doubling:not(.stackable).row.row > .column { + width: @fourColumn !important; + } + } +} + +& when (@variationGridStackable) { + /*------------------- + Stackable + --------------------*/ + + @media only screen and (max-width: @largestMobileScreen) { + .ui.stackable.grid { + width: auto; + margin-left: 0 !important; + margin-right: 0 !important; + } + .ui.stackable.grid > .row > .wide.column, + .ui.stackable.grid > .wide.column, + .ui.stackable.grid > .column.grid > .column, + .ui.stackable.grid > .column.row > .column, + .ui.stackable.grid > .row > .column, + .ui.stackable.grid > .column:not(.row), + .ui.grid > .stackable.stackable.stackable.row > .column { + width: 100% !important; + margin: 0 0 !important; + box-shadow: none !important; + padding: (@stackableRowSpacing / 2) (@stackableGutter / 2); + } + .ui.stackable.grid:not(.vertically) > .row { + margin: 0; + padding: 0; + } + + /* Coupling */ + .ui.container > .ui.stackable.grid > .column, + .ui.container > .ui.stackable.grid > .row > .column { + padding-left: 0 !important; + padding-right: 0 !important; + } + + /* Don't pad inside segment or nested grid */ + .ui.grid .ui.stackable.grid, + .ui.segment:not(.vertical) .ui.stackable.page.grid { + margin-left: -(@stackableGutter / 2) !important; + margin-right: -(@stackableGutter / 2) !important; + } + + /* Divided Stackable */ + .ui.stackable.divided.grid > .row:first-child > .column:first-child, + .ui.stackable.celled.grid > .row:first-child > .column:first-child, + .ui.stackable.divided.grid > .column:not(.row):first-child, + .ui.stackable.celled.grid > .column:not(.row):first-child { + border-top: none !important; + } + & when (@variationGridInverted) { + .ui.inverted.stackable.celled.grid > .column:not(.row), + .ui.inverted.stackable.divided.grid > .column:not(.row), + .ui.inverted.stackable.celled.grid > .row > .column, + .ui.inverted.stackable.divided.grid > .row > .column { + border-top: @stackableInvertedMobileBorder; + } + } + .ui.stackable.celled.grid > .column:not(.row), + .ui.stackable.divided:not(.vertically).grid > .column:not(.row), + .ui.stackable.celled.grid > .row > .column, + .ui.stackable.divided:not(.vertically).grid > .row > .column { + border-top: @stackableMobileBorder; + box-shadow: none !important; + padding-top: @stackableRowSpacing !important; + padding-bottom: @stackableRowSpacing !important; + } + & when (@variationGridCelled) { + .ui.stackable.celled.grid > .row { + box-shadow: none !important; + } + } + & when (@variationGridDivided) { + .ui.stackable.divided:not(.vertically).grid > .column:not(.row), + .ui.stackable.divided:not(.vertically).grid > .row > .column { + padding-left: 0 !important; + padding-right: 0 !important; + } + } + } + +} + +/*---------------------- + Only (Device) +-----------------------*/ + + +/* These include arbitrary class repetitions for forced specificity */ + +/* Mobile Only Hide */ +@media only screen and (max-width: @largestMobileScreen) { + .ui[class*="tablet only"].grid.grid.grid:not(.mobile), + .ui.grid.grid.grid > [class*="tablet only"].row:not(.mobile), + .ui.grid.grid.grid > [class*="tablet only"].column:not(.mobile), + .ui.grid.grid.grid > .row > [class*="tablet only"].column:not(.mobile) { + display: none !important; + } + .ui[class*="computer only"].grid.grid.grid:not(.mobile), + .ui.grid.grid.grid > [class*="computer only"].row:not(.mobile), + .ui.grid.grid.grid > [class*="computer only"].column:not(.mobile), + .ui.grid.grid.grid > .row > [class*="computer only"].column:not(.mobile) { + display: none !important; + } + .ui[class*="large screen only"].grid.grid.grid:not(.mobile), + .ui.grid.grid.grid > [class*="large screen only"].row:not(.mobile), + .ui.grid.grid.grid > [class*="large screen only"].column:not(.mobile), + .ui.grid.grid.grid > .row > [class*="large screen only"].column:not(.mobile) { + display: none !important; + } + .ui[class*="widescreen only"].grid.grid.grid:not(.mobile), + .ui.grid.grid.grid > [class*="widescreen only"].row:not(.mobile), + .ui.grid.grid.grid > [class*="widescreen only"].column:not(.mobile), + .ui.grid.grid.grid > .row > [class*="widescreen only"].column:not(.mobile) { + display: none !important; + } +} +/* Tablet Only Hide */ +@media only screen and (min-width: @tabletBreakpoint) and (max-width: @largestTabletScreen) { + .ui[class*="mobile only"].grid.grid.grid:not(.tablet), + .ui.grid.grid.grid > [class*="mobile only"].row:not(.tablet), + .ui.grid.grid.grid > [class*="mobile only"].column:not(.tablet), + .ui.grid.grid.grid > .row > [class*="mobile only"].column:not(.tablet) { + display: none !important; + } + .ui[class*="computer only"].grid.grid.grid:not(.tablet), + .ui.grid.grid.grid > [class*="computer only"].row:not(.tablet), + .ui.grid.grid.grid > [class*="computer only"].column:not(.tablet), + .ui.grid.grid.grid > .row > [class*="computer only"].column:not(.tablet) { + display: none !important; + } + .ui[class*="large screen only"].grid.grid.grid:not(.mobile), + .ui.grid.grid.grid > [class*="large screen only"].row:not(.mobile), + .ui.grid.grid.grid > [class*="large screen only"].column:not(.mobile), + .ui.grid.grid.grid > .row > [class*="large screen only"].column:not(.mobile) { + display: none !important; + } + .ui[class*="widescreen only"].grid.grid.grid:not(.mobile), + .ui.grid.grid.grid > [class*="widescreen only"].row:not(.mobile), + .ui.grid.grid.grid > [class*="widescreen only"].column:not(.mobile), + .ui.grid.grid.grid > .row > [class*="widescreen only"].column:not(.mobile) { + display: none !important; + } +} + +/* Computer Only Hide */ +@media only screen and (min-width: @computerBreakpoint) and (max-width: @largestSmallMonitor) { + .ui[class*="mobile only"].grid.grid.grid:not(.computer), + .ui.grid.grid.grid > [class*="mobile only"].row:not(.computer), + .ui.grid.grid.grid > [class*="mobile only"].column:not(.computer), + .ui.grid.grid.grid > .row > [class*="mobile only"].column:not(.computer) { + display: none !important; + } + .ui[class*="tablet only"].grid.grid.grid:not(.computer), + .ui.grid.grid.grid > [class*="tablet only"].row:not(.computer), + .ui.grid.grid.grid > [class*="tablet only"].column:not(.computer), + .ui.grid.grid.grid > .row > [class*="tablet only"].column:not(.computer) { + display: none !important; + } + .ui[class*="large screen only"].grid.grid.grid:not(.mobile), + .ui.grid.grid.grid > [class*="large screen only"].row:not(.mobile), + .ui.grid.grid.grid > [class*="large screen only"].column:not(.mobile), + .ui.grid.grid.grid > .row > [class*="large screen only"].column:not(.mobile) { + display: none !important; + } + .ui[class*="widescreen only"].grid.grid.grid:not(.mobile), + .ui.grid.grid.grid > [class*="widescreen only"].row:not(.mobile), + .ui.grid.grid.grid > [class*="widescreen only"].column:not(.mobile), + .ui.grid.grid.grid > .row > [class*="widescreen only"].column:not(.mobile) { + display: none !important; + } +} + +/* Large Screen Only Hide */ +@media only screen and (min-width: @largeMonitorBreakpoint) and (max-width: @largestLargeMonitor) { + .ui[class*="mobile only"].grid.grid.grid:not(.computer), + .ui.grid.grid.grid > [class*="mobile only"].row:not(.computer), + .ui.grid.grid.grid > [class*="mobile only"].column:not(.computer), + .ui.grid.grid.grid > .row > [class*="mobile only"].column:not(.computer) { + display: none !important; + } + .ui[class*="tablet only"].grid.grid.grid:not(.computer), + .ui.grid.grid.grid > [class*="tablet only"].row:not(.computer), + .ui.grid.grid.grid > [class*="tablet only"].column:not(.computer), + .ui.grid.grid.grid > .row > [class*="tablet only"].column:not(.computer) { + display: none !important; + } + .ui[class*="widescreen only"].grid.grid.grid:not(.mobile), + .ui.grid.grid.grid > [class*="widescreen only"].row:not(.mobile), + .ui.grid.grid.grid > [class*="widescreen only"].column:not(.mobile), + .ui.grid.grid.grid > .row > [class*="widescreen only"].column:not(.mobile) { + display: none !important; + } +} + +/* Widescreen Only Hide */ +@media only screen and (min-width: @widescreenMonitorBreakpoint) { + .ui[class*="mobile only"].grid.grid.grid:not(.computer), + .ui.grid.grid.grid > [class*="mobile only"].row:not(.computer), + .ui.grid.grid.grid > [class*="mobile only"].column:not(.computer), + .ui.grid.grid.grid > .row > [class*="mobile only"].column:not(.computer) { + display: none !important; + } + .ui[class*="tablet only"].grid.grid.grid:not(.computer), + .ui.grid.grid.grid > [class*="tablet only"].row:not(.computer), + .ui.grid.grid.grid > [class*="tablet only"].column:not(.computer), + .ui.grid.grid.grid > .row > [class*="tablet only"].column:not(.computer) { + display: none !important; + } +} + +& when (@variationGridCompact) { + /*----------------- + Compact + -----------------*/ + + .ui.ui.ui.compact.grid > .column:not(.row), + .ui.ui.ui.compact.grid > .row > .column { + padding-left: (@compactGutterWidth / 2); + padding-right: (@compactGutterWidth / 2); + } + + .ui.ui.ui.compact.grid > * { + padding-left: (@compactGutterWidth / 2); + padding-right: (@compactGutterWidth / 2); + } + + /* Row */ + .ui.ui.ui.compact.grid > .row { + padding-top: (@compactRowSpacing / 2); + padding-bottom: (@compactRowSpacing / 2); + } + + /* Columns */ + .ui.ui.ui.compact.grid > .column:not(.row) { + padding-top: (@compactRowSpacing / 2); + padding-bottom: (@compactRowSpacing / 2); + } + & when (@variationGridRelaxed) and (@variationGridCelled) { + /* Relaxed + Celled */ + .ui.compact.relaxed.celled.grid > .column:not(.row), + .ui.compact.relaxed.celled.grid > .row > .column { + padding: @compactCelledRelaxedPadding; + } + .ui.compact[class*="very relaxed"].celled.grid > .column:not(.row), + .ui.compact[class*="very relaxed"].celled.grid > .row > .column { + padding: @compactCelledVeryRelaxedPadding; + } + } + + /*----------------- + Very compact + -----------------*/ + + .ui.ui.ui[class*="very compact"].grid > .column:not(.row), + .ui.ui.ui[class*="very compact"].grid > .row > .column { + padding-left: (@veryCompactGutterWidth / 2); + padding-right: (@veryCompactGutterWidth / 2); + } + + .ui.ui.ui[class*="very compact"].grid > * { + padding-left: (@veryCompactGutterWidth / 2); + padding-right: (@veryCompactGutterWidth / 2); + } + + /* Row */ + .ui.ui.ui[class*="very compact"].grid > .row { + padding-top: (@veryCompactRowSpacing / 2); + padding-bottom: (@veryCompactRowSpacing / 2); + padding-left: (@veryCompactGutterWidth * 1.5); + padding-right: (@veryCompactGutterWidth * 1.5); + } + + /* Columns */ + .ui.ui.ui[class*="very compact"].grid > .column:not(.row) { + padding-top: (@veryCompactRowSpacing / 2); + padding-bottom: (@veryCompactRowSpacing / 2); + } + & when (@variationGridRelaxed) and (@variationGridCelled) { + /* Relaxed + Celled */ + .ui[class*="very compact"].relaxed.celled.grid > .column:not(.row), + .ui[class*="very compact"].relaxed.celled.grid > .row > .column { + padding: @veryCompactCelledRelaxedPadding; + } + .ui[class*="very compact"][class*="very relaxed"].celled.grid > .column:not(.row), + .ui[class*="very compact"][class*="very relaxed"].celled.grid > .row > .column { + padding: @veryCompactCelledVeryRelaxedPadding; + } + } +} + + +.loadUIOverrides(); diff --git a/semantic/src/definitions/collections/menu.less b/semantic/src/definitions/collections/menu.less new file mode 100644 index 0000000..3d712ed --- /dev/null +++ b/semantic/src/definitions/collections/menu.less @@ -0,0 +1,1939 @@ +/* + * # Fomantic - Menu + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Copyright 2015 Contributor + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + + +/******************************* + Theme +*******************************/ + +@type : 'collection'; +@element : 'menu'; + +@import (multiple) '../../theme.config'; + +/******************************* + Standard +*******************************/ + +/*-------------- + Menu +---------------*/ + +.ui.menu { + display: flex; + margin: @margin; + font-family: @fontFamily; + background: @background; + font-weight: @fontWeight; + border: @border; + box-shadow: @boxShadow; + border-radius: @borderRadius; + min-height: @minHeight; +} + +.ui.menu:after { + content: ''; + display: block; + height: 0; + clear: both; + visibility: hidden; +} + +.ui.menu:first-child { + margin-top: 0; +} +.ui.menu:last-child { + margin-bottom: 0; +} + + +/*-------------- + Sub-Menu +---------------*/ + +.ui.menu .menu { + margin: 0; +} + +.ui.menu:not(.vertical) > .menu { + display: flex; +} + +/*-------------- + Item +---------------*/ + +.ui.menu:not(.vertical) .item { + display: flex; + align-items: center; +} + +.ui.menu .item { + position: relative; + vertical-align: middle; + line-height: 1; + text-decoration: none; + -webkit-tap-highlight-color: transparent; + flex: 0 0 auto; + user-select: none; + + background: @itemBackground; + padding: @itemVerticalPadding @itemHorizontalPadding; + text-transform: @itemTextTransform; + color: @itemTextColor; + font-weight: @itemFontWeight; + transition: @itemTransition; +} + +.ui.menu > .item:first-child { + border-radius: @borderRadius 0 0 @borderRadius; +} + +/* Border */ +.ui.menu .item:before { + position: absolute; + content: ''; + top: 0; + right: 0; + height: 100%; + + width: @dividerSize; + background: @dividerBackground; +} + +/*-------------- + Text Content +---------------*/ + +.ui.menu .text.item > *, +.ui.menu .item > a:not(.ui), +.ui.menu .item > p:only-child { + user-select: text; + line-height: @textLineHeight; +} +.ui.menu .item > p:first-child { + margin-top: 0; +} +.ui.menu .item > p:last-child { + margin-bottom: 0; +} + +/*-------------- + Icons +---------------*/ + +.ui.menu .item > i.icon { + opacity: @iconOpacity; + float: @iconFloat; + margin: @iconMargin; +} + +/*-------------- + Button +---------------*/ + +.ui.menu:not(.vertical) .item > .button { + position: relative; + top: @buttonOffset; + margin: @buttonMargin; + padding-bottom: @buttonVerticalPadding; + padding-top: @buttonVerticalPadding; + font-size: @buttonSize; +} + +/*---------------- + Grid / Container +-----------------*/ + +.ui.menu > .grid, +.ui.menu > .container { + display: flex; + align-items: inherit; + flex-direction: inherit; +} + +/*-------------- + Inputs +---------------*/ + +.ui.menu .item > .input { + width: 100%; +} +.ui.menu:not(.vertical) .item > .input { + position: relative; + top: @inputOffset; + margin: @inputVerticalMargin 0; +} +.ui.menu .item > .input input { + font-size: @inputSize; + padding-top: @inputVerticalPadding; + padding-bottom: @inputVerticalPadding; +} + + +/*-------------- + Header +---------------*/ + +.ui.menu .header.item, +.ui.vertical.menu .header.item { + margin: 0; + background: @headerBackground; + text-transform: @headerTextTransform; + font-weight: @headerWeight; +} + +& when (@variationMenuVertical) { + .ui.vertical.menu .item > .header:not(.ui) { + margin: @verticalHeaderMargin; + font-size: @verticalHeaderFontSize; + font-weight: @verticalHeaderFontWeight; + } +} + +/*-------------- + Dropdowns +---------------*/ + + +/* Dropdown Icon */ +.ui.menu .item > i.dropdown.icon { + padding: 0; + float: @dropdownIconFloat; + margin: 0 0 0 @dropdownIconDistance; +} + +/* Menu */ +.ui.menu .dropdown.item .menu { + min-width: e("calc(100% - 1px)"); + border-radius: 0 0 @dropdownMenuBorderRadius @dropdownMenuBorderRadius; + background: @dropdownBackground; + margin: @dropdownMenuDistance 0 0; + box-shadow: @dropdownMenuBoxShadow; + flex-direction: column !important; +} + + +/* Menu Items */ +.ui.menu .ui.dropdown .menu > .item { + margin: 0; + text-align: left; + font-size: @dropdownItemFontSize !important; + padding: @dropdownItemPadding !important; + background: @dropdownItemBackground !important; + color: @dropdownItemColor !important; + text-transform: @dropdownItemTextTransform !important; + font-weight: @dropdownItemFontWeight !important; + box-shadow: @dropdownItemBoxShadow !important; + transition: @dropdownItemTransition !important; +} +.ui.menu .ui.dropdown .menu > .item:hover { + background: @dropdownHoveredItemBackground !important; + color: @dropdownHoveredItemColor !important; +} +.ui.menu .ui.dropdown .menu > .selected.item { + background: @dropdownSelectedItemBackground !important; + color: @dropdownSelectedItemColor !important; +} +.ui.menu .ui.dropdown .menu > .active.item { + background: @dropdownActiveItemBackground !important; + font-weight: @dropdownActiveItemFontWeight !important; + color: @dropdownActiveItemColor !important; +} + +.ui.menu .ui.dropdown.item .menu .item:not(.filtered) { + display: block; +} +.ui.menu .ui.dropdown .menu > .item > .icons, +.ui.menu .ui.dropdown .menu > .item > i.icon:not(.dropdown) { + display: inline-block; + font-size: @dropdownItemIconFontSize !important; + float: @dropdownItemIconFloat; + margin: @dropdownItemIconMargin !important; +} + +& when (@variationMenuSecondary) or (@variationMenuText) { + /* Secondary */ + .ui.secondary.menu .dropdown.item > .menu, + .ui.text.menu .dropdown.item > .menu { + border-radius: @dropdownMenuBorderRadius; + margin-top: @secondaryDropdownMenuDistance; + } +} + +/* Pointing */ +.ui.menu .pointing.dropdown.item .menu { + margin-top: @pointingDropdownMenuDistance; +} + +& when (@variationMenuInverted) { + /* Inverted */ + .ui.inverted.menu .search.dropdown.item > .search, + .ui.inverted.menu .search.dropdown.item > .text { + color: @invertedSelectionDropdownColor; + } +} + +& when (@variationMenuVertical) { + /* Vertical */ + .ui.vertical.menu .dropdown.item > i.icon { + float: right; + content: "\f0da"; + margin-left: 1em; + } + .ui.vertical.menu .dropdown.item .menu { + left: 100%; + /* IE needs 0, all others support max-content to show dropdown icon inline, so keep both settings! */ + min-width: 0; + min-width: max-content; + margin: 0 0 0 @dropdownMenuDistance; + box-shadow: @dropdownVerticalMenuBoxShadow; + border-radius: 0 @dropdownMenuBorderRadius @dropdownMenuBorderRadius @dropdownMenuBorderRadius; + } + .ui.vertical.menu .dropdown.item.upward .menu { + bottom: 0; + } + .ui.vertical.menu .dropdown.item:not(.upward) .menu { + top: 0; + } + .ui.vertical.menu .active.dropdown.item { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + .ui.vertical.menu .dropdown.active.item { + box-shadow: none; + } +} + +/* Evenly Divided */ +.ui.item.menu .dropdown .menu .item { + width: 100%; +} + +/*-------------- + Labels +---------------*/ + +.ui.menu .item > .label:not(.floating) { + margin-left: @labelTextMargin; + padding: @labelVerticalPadding @labelHorizontalPadding; +} +& when (@variationMenuVertical) { + .ui.vertical.menu .item > .label { + margin-top: @labelOffset; + margin-bottom: @labelOffset; + padding: @labelVerticalPadding @labelHorizontalPadding; + } +} +.ui.menu .item > .floating.label { + padding: @labelVerticalPadding @labelHorizontalPadding; +} +.ui.menu .item > .label { + background: @labelBackground; + color: @labelTextColor; +} +.ui.menu .item > .image.label img { + margin: @imageLabelImageMargin; + height: @imageLabelHeight; +} +/*-------------- + Images +---------------*/ + +.ui.menu .item > img:not(.ui) { + display: inline-block; + vertical-align: middle; + margin: @imageMargin; + width: @imageWidth; +} +& when (@variationMenuVertical) { + .ui.vertical.menu .item > img:not(.ui):only-child { + display: block; + max-width: 100%; + width: @verticalImageWidth; + } +} + +/******************************* + Coupling +*******************************/ + +/*-------------- + List +---------------*/ + +/* Menu divider shouldnt apply */ +.ui.menu .list .item:before { + background: none !important; +} + +& when (@variationMenuVertical) { + /*-------------- + Sidebar + ---------------*/ + + /* Show vertical dividers below last */ + + .ui.vertical.sidebar.menu > .item:first-child:before { + display: block !important; + } + .ui.vertical.sidebar.menu > .item::before { + top: auto; + bottom: 0; + } +} + +/*-------------- + Container +---------------*/ + +@media only screen and (max-width: @largestMobileScreen) { + .ui.menu > .ui.container { + width: 100% !important; + margin-left: 0 !important; + margin-right: 0 !important; + } +} +@media only screen and (min-width: @tabletBreakpoint) { + .ui.menu:not(.secondary):not(.text):not(.tabular):not(.borderless) > .container > .item:not(.right):not(.borderless):first-child { + border-left: @dividerSize solid @dividerBackground; + } + .ui.menu:not(.secondary):not(.text):not(.tabular):not(.borderless) > .container > .right.item:not(.borderless):last-child, + .ui.menu:not(.secondary):not(.text):not(.tabular):not(.borderless) > .container > .right.menu > .item:not(.borderless):last-child { + border-right: @dividerSize solid @dividerBackground; + } +} + + +/******************************* + States +*******************************/ + +/*-------------- + Hover +---------------*/ + + +.ui.link.menu .item:hover, +.ui.menu .dropdown.item:hover, +.ui.menu .link.item:hover, +.ui.menu a.item:hover { + cursor: pointer; + background: @hoverItemBackground; + color: @hoverItemTextColor; +} + + +/*-------------- + Pressed +---------------*/ + +.ui.link.menu .item:active, +.ui.menu .link.item:active, +.ui.menu a.item:active { + background: @pressedItemBackground; + color: @pressedItemTextColor; +} + + +/*-------------- + Active +---------------*/ + +.ui.menu .active.item { + background: @activeItemBackground; + color: @activeItemTextColor; + font-weight: @activeItemFontWeight; + box-shadow: @activeItemBoxShadow; +} +.ui.menu .active.item > i.icon { + opacity: @activeIconOpacity; +} + +/*-------------- + Active Hover +---------------*/ + +.ui.menu .active.item:hover, +.ui.vertical.menu .active.item:hover { + background-color: @activeHoverItemBackground; + color: @activeHoverItemColor; +} + + +/*-------------- + Disabled +---------------*/ + +.ui.ui.menu .item.disabled { + cursor: default; + background-color: transparent; + color: @disabledTextColor; + pointer-events: none; +} + + +/******************************* + Types +*******************************/ + +/*------------------ +Floated Menu / Item +-------------------*/ + +/* Left Floated */ +.ui.menu:not(.vertical) .left.item, +.ui.menu:not(.vertical) .left.menu { + display: flex; + margin-right: auto !important; +} +/* Right Floated */ +.ui.menu:not(.vertical) .right.item, +.ui.menu:not(.vertical) .right.menu { + display: flex; + margin-left: auto !important; +} + +.ui.menu:not(.vertical) :not(.dropdown) > .left.menu, +.ui.menu:not(.vertical) :not(.dropdown) > .right.menu { + display: inherit; +} + +/* Center */ +.ui.menu:not(.vertical) .center.item, +.ui.menu:not(.vertical) .center.menu { + display: flex; + margin-left: auto !important; + margin-right: auto !important; +} + +/* Swapped Borders */ +.ui.menu .right.item::before, +.ui.menu .right.menu > .item::before { + right: auto; + left: 0; +} + +/* Remove Outer Borders */ +.ui.menu .center.item:last-child::before, +.ui.menu .center.menu > .item:last-child::before { + display: none; +} + +& when (@variationMenuVertical) { + /*-------------- + Vertical + ---------------*/ + + .ui.vertical.menu { + display: block; + flex-direction: column; + background: @verticalBackground; + box-shadow: @verticalBoxShadow; + } + + /*--- Item ---*/ + .ui.vertical.menu .item { + display: block; + background: @verticalItemBackground; + border-top: none; + border-right: none; + } + .ui.vertical.menu > .item:first-child { + border-radius: @borderRadius @borderRadius 0 0; + } + .ui.vertical.menu > .item:last-child { + border-radius: 0 0 @borderRadius @borderRadius; + } + + /*--- Label ---*/ + .ui.vertical.menu .item > .label { + float: right; + text-align: center; + } + + /*--- Icon ---*/ + .ui.vertical.menu .item > i.icon, + .ui.vertical.menu .item > i.icons { + width: @iconWidth; + float: @verticalIconFloat; + margin: @verticalIconMargin; + } + .ui.vertical.menu .item > .label + i.icon { + float: @labelAndIconFloat; + margin: @labelAndIconMargin; + } + + + /*--- Border ---*/ + .ui.vertical.menu .item:before { + position: absolute; + content: ''; + top: 0; + left: 0; + width: 100%; + height: @dividerSize; + background: @verticalDividerBackground; + } + + .ui.vertical.menu .item:first-child:before { + display: none !important; + } + + + /*--- Sub Menu ---*/ + .ui.vertical.menu .item > .menu { + margin: @subMenuMargin; + } + .ui.vertical.menu .menu .item { + background: none; + padding: @subMenuVerticalPadding @subMenuHorizontalPadding; + font-size: @subMenuFontSize; + color: @subMenuTextColor; + } + .ui.vertical.menu .item .menu a.item:hover, + .ui.vertical.menu .item .menu .link.item:hover { + color: @darkTextColor; + } + .ui.vertical.menu .menu .item:before { + display: none; + } + + /* Vertical Active */ + .ui.vertical.menu .active.item { + background: @activeItemBackground; + border-radius: 0; + box-shadow: @verticalActiveBoxShadow; + } + .ui.vertical.menu > .active.item:first-child { + border-radius: @borderRadius @borderRadius 0 0; + } + .ui.vertical.menu > .active.item:last-child { + border-radius: 0 0 @borderRadius @borderRadius; + } + .ui.vertical.menu > .active.item:only-child { + border-radius: @borderRadius; + } + .ui.vertical.menu .active.item .menu .active.item { + border-left: none; + } + .ui.vertical.menu .item .menu .active.item { + background-color: @subMenuActiveBackground; + font-weight: @subMenuActiveFontWeight; + color: @subMenuActiveTextColor; + } +} + +& when (@variationMenuTabular) { + /*-------------- + Tabular + ---------------*/ + + .ui.tabular.menu { + border-radius: 0; + box-shadow: none !important; + border: none; + background: @tabularBackground; + border-bottom: @tabularBorderWidth solid @tabularBorderColor; + } + .ui.tabular.fluid.menu { + width: @tabularFluidWidth !important; + } + .ui.tabular.menu .item { + background: transparent; + border-bottom: none; + + border-left: @tabularBorderWidth solid transparent; + border-right: @tabularBorderWidth solid transparent; + border-top: @tabularOppositeBorderWidth solid transparent; + padding: @tabularVerticalPadding @tabularHorizontalPadding; + color: @tabularTextColor; + } + .ui.tabular.menu .item:before { + display: none; + } + + /* Hover */ + .ui.tabular.menu .item:hover { + background-color: transparent; + color: @tabularHoveredTextColor; + } + + /* Active */ + .ui.tabular.menu .active.item { + background: @tabularActiveBackground; + color: @tabularActiveColor; + border-top-width: @tabularBorderWidth; + border-color: @tabularBorderColor; + font-weight: @tabularActiveWeight; + margin-bottom: -@tabularBorderWidth; + box-shadow: @tabularActiveBoxShadow; + border-radius: @tabularBorderRadius @tabularBorderRadius 0 0 !important; + } + + /* Coupling with segment for attachment */ + .ui.tabular.menu + .attached:not(.top).segment, + .ui.tabular.menu + .attached:not(.top).segment + .attached:not(.top).segment { + border-top: none; + margin-left: 0; + margin-top: 0; + margin-right: 0; + width: 100%; + } + .top.attached.segment + .ui.bottom.tabular.menu { + position: relative; + width: @tabularFluidWidth; + left: -@tabularFluidOffset; + } + + /* Bottom Vertical Tabular */ + .ui.bottom.tabular.menu { + background: @tabularBackground; + border-radius: 0; + box-shadow: none !important; + border-bottom: none; + border-top: @tabularBorderWidth solid @tabularBorderColor; + } + .ui.bottom.tabular.menu .item { + background: none; + border-left: @tabularBorderWidth solid transparent; + border-right: @tabularBorderWidth solid transparent; + border-bottom: @tabularBorderWidth solid transparent; + border-top: none; + } + .ui.bottom.tabular.menu .active.item { + background: @tabularActiveBackground; + color: @tabularActiveColor; + border-color: @tabularBorderColor; + margin: -@tabularBorderWidth 0 0 0; + border-radius: 0 0 @tabularBorderRadius @tabularBorderRadius !important; + } + & when (@variationMenuVertical) { + /* Vertical Tabular (Left) */ + .ui.vertical.tabular.menu { + background: @tabularVerticalBackground; + border-radius: 0; + box-shadow: none !important; + border-bottom: none; + border-right: @tabularBorderWidth solid @tabularBorderColor; + } + .ui.vertical.tabular.menu .item { + background: none; + border-left: @tabularBorderWidth solid transparent; + border-bottom: @tabularBorderWidth solid transparent; + border-top: @tabularBorderWidth solid transparent; + border-right: none; + } + .ui.vertical.tabular.menu .active.item { + background: @tabularActiveBackground; + color: @tabularActiveColor; + border-color: @tabularBorderColor; + margin: 0 -@tabularBorderWidth 0 0; + border-radius: @tabularBorderRadius 0 0 @tabularBorderRadius !important; + } + + /* Vertical Right Tabular */ + .ui.vertical.right.tabular.menu { + background: @tabularVerticalBackground; + border-radius: 0; + box-shadow: none !important; + border-bottom: none; + border-right: none; + border-left: @tabularBorderWidth solid @tabularBorderColor; + } + .ui.vertical.right.tabular.menu .item { + background: none; + border-right: @tabularBorderWidth solid transparent; + border-bottom: @tabularBorderWidth solid transparent; + border-top: @tabularBorderWidth solid transparent; + border-left: none; + } + .ui.vertical.right.tabular.menu .active.item { + background: @tabularActiveBackground; + color: @tabularActiveColor; + border-color: @tabularBorderColor; + margin: 0 0 0 -@tabularBorderWidth; + border-radius: 0 @tabularBorderRadius @tabularBorderRadius 0 !important; + } + } + /* Dropdown */ + .ui.tabular.menu .active.dropdown.item { + margin-bottom: 0; + border-left: @tabularBorderWidth solid transparent; + border-right: @tabularBorderWidth solid transparent; + border-top: @tabularOppositeBorderWidth solid transparent; + border-bottom: none; + } +} + + +& when (@variationMenuPagination) { + /*-------------- + Pagination + ---------------*/ + + .ui.pagination.menu { + margin: 0; + display: inline-flex; + vertical-align: middle; + } + .ui.pagination.menu .item:last-child { + border-radius: 0 @borderRadius @borderRadius 0; + } + .ui.compact.menu .item:last-child { + border-radius: 0 @borderRadius @borderRadius 0; + } + .ui.pagination.menu .item:last-child:before { + display: none; + } + + .ui.pagination.menu .item { + min-width: @paginationMinWidth; + text-align: center; + } + .ui.pagination.menu .icon.item i.icon { + vertical-align: top; + } + + /* Active */ + .ui.pagination.menu .active.item { + border-top: none; + padding-top: @itemVerticalPadding; + background-color: @paginationActiveBackground; + color: @paginationActiveTextColor; + box-shadow: none; + } +} + +& when (@variationMenuSecondary) { + /*-------------- + Secondary + ---------------*/ + + .ui.secondary.menu { + background: @secondaryBackground; + margin-left: -@secondaryItemSpacing; + margin-right: -@secondaryItemSpacing; + border-radius: 0; + border: none; + box-shadow: none; + } + + /* Item */ + .ui.secondary.menu .item { + align-self: center; + box-shadow: none; + border: none; + padding: @secondaryItemPadding; + margin: @secondaryItemMargin; + background: @secondaryItemBackground; + transition: @secondaryItemTransition; + border-radius: @secondaryItemBorderRadius; + } + + /* No Divider */ + .ui.secondary.menu .item:before { + display: none !important; + } + + /* Header */ + .ui.secondary.menu .header.item { + border-radius: 0; + border-right: @secondaryHeaderBorder; + background: @secondaryHeaderBackground; + } + + /* Image */ + .ui.secondary.menu .item > img:not(.ui) { + margin: 0; + } + + /* Hover */ + .ui.secondary.menu .dropdown.item:hover, + .ui.secondary.menu .link.item:hover, + .ui.secondary.menu a.item:hover { + background: @secondaryHoverItemBackground; + color: @secondaryHoverItemColor; + } + + /* Active */ + .ui.secondary.menu .active.item { + box-shadow: none; + background: @secondaryActiveItemBackground; + color: @secondaryActiveItemColor; + border-radius: @secondaryItemBorderRadius; + } + + /* Active Hover */ + .ui.secondary.menu .active.item:hover { + box-shadow: none; + background: @secondaryActiveHoverItemBackground; + color: @secondaryActiveHoverItemColor; + } + + & when (@variationMenuInverted) { + /* Inverted */ + .ui.secondary.inverted.menu .link.item:not(.disabled), + .ui.secondary.inverted.menu a.item:not(.disabled) { + color: @secondaryInvertedColor; + } + .ui.secondary.inverted.menu .dropdown.item:hover, + .ui.secondary.inverted.menu .link.item:hover, + .ui.secondary.inverted.menu a.item:hover { + background: @secondaryInvertedHoverBackground; + color: @secondaryInvertedHoverColor; + } + .ui.secondary.inverted.menu .active.item { + background: @secondaryInvertedActiveBackground; + color: @secondaryInvertedActiveColor; + } + } + /* Fix item margins */ + .ui.secondary.item.menu { + margin-left: 0; + margin-right: 0; + } + .ui.secondary.item.menu .item:last-child { + margin-right: 0; + } + & when (@variationMenuAttached) { + .ui.secondary.attached.menu { + box-shadow: none; + } + } + & when (@variationMenuVertical) { + /*--------------------- + Secondary Vertical + -----------------------*/ + + /* Sub Menu */ + .ui.vertical.secondary.menu .item:not(.dropdown) > .menu { + margin: @secondaryMenuSubMenuMargin; + } + .ui.vertical.secondary.menu .item:not(.dropdown) > .menu > .item { + margin: @secondaryMenuSubMenuItemMargin; + padding: @secondaryMenuSubMenuItemPadding; + } + + + .ui.secondary.vertical.menu > .item { + border: none; + margin: @secondaryVerticalItemMargin; + border-radius: @secondaryVerticalItemBorderRadius !important; + } + .ui.secondary.vertical.menu > .header.item { + border-radius: 0; + } + + /* Sub Menu */ + .ui.vertical.secondary.menu .item > .menu .item { + background-color: transparent; + } + + /* Inverted */ + .ui.secondary.inverted.menu { + background-color: transparent; + } + } + + & when (@variationMenuPointing) { + /*--------------------- + Secondary Pointing + -----------------------*/ + + .ui.secondary.pointing.menu { + margin-left: 0; + margin-right: 0; + border-bottom: @secondaryPointingBorderWidth solid @secondaryPointingBorderColor; + } + + .ui.secondary.pointing.menu .item { + border-bottom-color: transparent; + border-bottom-style: solid; + border-radius: 0; + align-self: flex-end; + + margin: 0 0 -@secondaryPointingBorderWidth; + padding: @secondaryPointingItemVerticalPadding @secondaryPointingItemHorizontalPadding; + border-bottom-width: @secondaryPointingBorderWidth; + transition: @secondaryItemTransition; + } + .ui.secondary.pointing.menu .ui.dropdown .menu .item { + border-bottom-width: 0; + } + + .ui.secondary.pointing.menu .item > .label:not(.floating) { + margin-top: -@labelVerticalPadding; + margin-bottom: -@labelVerticalPadding; + } + .ui.secondary.pointing.menu .item > .circular.label { + margin-top: -@circularLabelVerticalPadding; + margin-bottom: -@circularLabelVerticalPadding; + } + + /* Item Types */ + .ui.secondary.pointing.menu .header.item { + color: @secondaryPointingHeaderColor !important; + } + .ui.secondary.pointing.menu .text.item { + box-shadow: none !important; + } + .ui.secondary.pointing.menu .item:after { + display: none; + } + + /* Hover */ + .ui.secondary.pointing.menu .dropdown.item:hover, + .ui.secondary.pointing.menu .link.item:hover, + .ui.secondary.pointing.menu a.item:hover { + background-color: transparent; + color: @secondaryPointingHoverTextColor; + } + + /* Pressed */ + .ui.secondary.pointing.menu .dropdown.item:active, + .ui.secondary.pointing.menu .link.item:active, + .ui.secondary.pointing.menu a.item:active { + background-color: transparent; + border-color: @secondaryPointingBorderColor; + } + + /* Active */ + .ui.secondary.pointing.menu .active.item { + background-color: transparent; + box-shadow: none; + border-color: @secondaryPointingActiveBorderColor; + font-weight: @secondaryPointingActiveFontWeight; + color: @secondaryPointingActiveTextColor; + } + + /* Active Hover */ + .ui.secondary.pointing.menu .active.item:hover { + border-color: @secondaryPointingActiveHoverBorderColor; + color: @secondaryPointingActiveHoverTextColor; + } + + /* Active Dropdown */ + .ui.secondary.pointing.menu .active.dropdown.item { + border-color: @secondaryPointingActiveDropdownBorderColor; + } + & when (@variationMenuVertical) { + /* Vertical Pointing */ + .ui.secondary.vertical.pointing.menu { + border-bottom-width: 0; + border-right-width: @secondaryPointingBorderWidth; + border-right-style: solid; + border-right-color: @secondaryPointingBorderColor; + } + .ui.secondary.vertical.pointing.menu .item { + border-bottom: none; + border-right-style: solid; + border-right-color: transparent; + border-radius: 0 !important; + margin: @secondaryVerticalPointingItemMargin; + border-right-width: @secondaryPointingBorderWidth; + } + + /* Vertical Active */ + .ui.secondary.vertical.pointing.menu .active.item { + border-color: @secondaryPointingActiveBorderColor; + } + } + & when (@variationMenuInverted) { + /* Inverted */ + .ui.secondary.inverted.pointing.menu { + border-color: @secondaryPointingInvertedBorderColor; + } + + .ui.secondary.inverted.pointing.menu .item:not(.disabled) { + color: @secondaryPointingInvertedItemTextColor; + } + .ui.secondary.inverted.pointing.menu .header.item { + color: @secondaryPointingInvertedItemHeaderColor !important; + } + + /* Hover */ + .ui.secondary.inverted.pointing.menu .link.item:hover, + .ui.secondary.inverted.pointing.menu a.item:hover { + color: @secondaryPointingInvertedItemHoverTextColor; + } + + + /* Active */ + .ui.ui.secondary.inverted.pointing.menu .active.item { + border-color: @secondaryPointingInvertedActiveBorderColor; + color: @secondaryPointingInvertedActiveColor; + background-color: transparent; + } + } + } +} + +& when (@variationMenuText) { + /*-------------- + Text Menu + ---------------*/ + + .ui.text.menu { + background: none transparent; + border-radius: 0; + box-shadow: none; + border: none; + + margin: @textMenuMargin; + } + .ui.text.menu .item { + border-radius: 0; + box-shadow: none; + align-self: center; + margin: @textMenuItemMargin; + padding: @textMenuItemPadding; + font-weight: @textMenuItemFontWeight; + color: @textMenuItemColor; + transition: @textMenuItemTransition; + } + + /* Border */ + .ui.text.menu .item:before, + .ui.text.menu .menu .item:before { + display: none !important; + } + + /* Header */ + .ui.text.menu .header.item { + background-color: transparent; + opacity: 1; + color: @textMenuHeaderColor; + font-size: @textMenuHeaderSize; + text-transform: @textMenuHeaderTextTransform; + font-weight: @textMenuHeaderFontWeight; + } + + /* Image */ + .ui.text.menu .item > img:not(.ui) { + margin: 0; + } + + /*--- fluid text ---*/ + .ui.text.item.menu .item { + margin: 0; + } + & when (@variationMenuVertical) { + /*--- vertical text ---*/ + .ui.vertical.text.menu { + margin: @textVerticalMenuMargin; + } + .ui.vertical.text.menu:first-child { + margin-top: 0; + } + .ui.vertical.text.menu:last-child { + margin-bottom: 0; + } + .ui.vertical.text.menu .item { + margin: @textVerticalMenuItemMargin; + padding-left: 0; + padding-right: 0; + } + .ui.vertical.text.menu .item > i.icon { + float: @textVerticalMenuIconFloat; + margin: @iconMargin; + } + .ui.vertical.text.menu .header.item { + margin: @textVerticalMenuHeaderMargin; + } + + /* Vertical Sub Menu */ + .ui.vertical.text.menu .item:not(.dropdown) > .menu { + margin: @textMenuSubMenuMargin; + } + .ui.vertical.text.menu .item:not(.dropdown) > .menu > .item { + margin: @textMenuSubMenuItemMargin; + padding: @textMenuSubMenuItemPadding; + } + } + /*--- hover ---*/ + .ui.text.menu .item:hover { + opacity: 1; + background-color: transparent; + } + + /*--- active ---*/ + .ui.text.menu .active.item { + background-color: transparent; + border: none; + box-shadow: none; + font-weight: @textMenuActiveItemFontWeight; + color: @textMenuActiveItemColor; + } + + /*--- active hover ---*/ + .ui.text.menu .active.item:hover { + background-color: transparent; + } + & when (@variationMenuPointing) { + /* Disable Bariations */ + .ui.text.pointing.menu .active.item:after { + box-shadow: none; + } + } + & when (@variationMenuAttached) { + .ui.text.attached.menu { + box-shadow: none; + } + } + & when (@variationMenuInverted) { + /* Inverted */ + .ui.inverted.text.menu, + .ui.inverted.text.menu .item, + .ui.inverted.text.menu .item:hover, + .ui.inverted.text.menu .active.item { + background-color: transparent; + } + } + & when (@variationMenuFluid) { + /* Fluid */ + .ui.fluid.text.menu { + margin-left: 0; + margin-right: 0; + } + } +} + +/*-------------- + Icon Only +---------------*/ + +/* Vertical Menu */ +.ui.vertical.icon.menu { + display: inline-block; + width: auto; +} + +/* Item */ +.ui.icon.menu .item { + height: auto; + text-align: @iconMenuTextAlign; + color: @iconMenuItemColor; +} + +/* Icon */ +.ui.icon.menu .item > i.icon:not(.dropdown) { + margin: 0; + opacity: 1; +} + +/* Icon Gylph */ +.ui.icon.menu i.icon:before { + opacity: 1; +} + +/* (x) Item Icon */ +.ui.menu .icon.item > i.icon { + width: auto; + margin: 0 auto; +} + +/* Vertical Icon */ +.ui.vertical.icon.menu .item > i.icon:not(.dropdown) { + display: block; + opacity: 1; + margin: 0 auto; + float: none; +} + +/* Inverted */ +.ui.inverted.icon.menu .item { + color: @iconMenuInvertedItemColor; +} + +& when (@variationMenuLabeled) { + /*-------------- + Labeled Icon + ---------------*/ + + /* Menu */ + .ui.labeled.icon.menu { + text-align: center; + } + + /* Item */ + .ui.labeled.icon.menu .item { + min-width: @labeledIconMinWidth; + flex-direction: column; + } + + /* Icon */ + .ui.labeled.icon.menu > .item > i.icon:not(.dropdown) { + height: 1em; + display: block; + font-size: @labeledIconSize !important; + margin: 0 auto @labeledIconTextMargin !important; + } + & when (@variationMenuFluid) { + /* Fluid */ + .ui.fluid.labeled.icon.menu > .item { + min-width: 0; + } + } +} + + +/******************************* + Variations +*******************************/ + +& when (@variationMenuStackable) { + /*-------------- + Stackable + ---------------*/ + + @media only screen and (max-width: @largestMobileScreen) { + .ui.stackable.menu { + flex-direction: column; + } + .ui.stackable.menu .item { + width: 100% !important; + } + .ui.stackable.menu .item:before { + position: absolute; + content: ''; + top: auto; + bottom: 0; + left: 0; + width: 100%; + height: @dividerSize; + background: @verticalDividerBackground; + } + + .ui.stackable.menu .left.menu, + .ui.stackable.menu .left.item { + margin-right: 0 !important; + } + .ui.stackable.menu .right.menu, + .ui.stackable.menu .right.item { + margin-left: 0 !important; + } + .ui.stackable.menu .center.menu, + .ui.stackable.menu .center.item { + margin-left: 0 !important; + margin-right: 0 !important; + } + + .ui.stackable.menu .right.menu, + .ui.stackable.menu .center.menu, + .ui.stackable.menu .left.menu { + flex-direction: column; + } + } +} + +/*-------------- + Colors +---------------*/ + +each(@colors, { + @color: replace(@key, '@', ''); + @c: @colors[@@color][color]; + + & when not (@color=secondary) { + .ui.ui.ui.menu .@{color}.active.item, + .ui.ui.@{color}.menu .active.item:hover, + .ui.ui.@{color}.menu .active.item { + & when not (@secondaryPointingActiveBorderColor = currentColor) { + border-color: @c; + } + color: @c; + } + } +}) + +& when (@variationMenuInverted) { + /*-------------- + Inverted + ---------------*/ + + .ui.inverted.menu { + border: @invertedBorder; + background: @invertedBackground; + box-shadow: @invertedBoxShadow; + } + + /* Menu Item */ + .ui.inverted.menu .item, + .ui.inverted.menu .item > a:not(.ui) { + background: @invertedItemBackground; + color: @invertedItemTextColor; + } + .ui.inverted.menu .item.menu { + background: @invertedSubMenuBackground; + } + + /*--- Border ---*/ + .ui.inverted.menu .item:before { + background: @invertedDividerBackground; + } + & when (@variationMenuVertical) { + .ui.vertical.inverted.menu .item:before { + background: @invertedVerticalDividerBackground; + } + /* Sub Menu */ + .ui.vertical.inverted.menu .menu .item, + .ui.vertical.inverted.menu .menu .item a:not(.ui) { + color: @invertedSubMenuColor; + } + } + /* Header */ + .ui.inverted.menu .header.item { + margin: 0; + background: @invertedHeaderBackground; + box-shadow: none; + } + + /* Disabled */ + .ui.ui.inverted.menu .item.disabled { + color: @invertedDisabledTextColor; + } + + /*--- Hover ---*/ + .ui.link.inverted.menu .item:hover, + .ui.inverted.menu .dropdown.item:hover, + .ui.inverted.menu .link.item:hover, + .ui.inverted.menu a.item:hover { + background: @invertedHoverBackground; + color: @invertedHoverColor; + } + & when (@variationMenuVertical) { + .ui.vertical.inverted.menu .item .menu a.item:hover, + .ui.vertical.inverted.menu .item .menu .link.item:hover { + background: @invertedSubMenuBackground; + color: @invertedSubMenuHoverColor; + } + } + /*--- Pressed ---*/ + .ui.inverted.menu a.item:active, + .ui.inverted.menu .link.item:active{ + background: @invertedMenuPressedBackground; + color: @invertedMenuPressedColor; + } + + /*--- Active ---*/ + .ui.inverted.menu .active.item { + background: @invertedActiveBackground; + color: @invertedActiveColor !important; + } + & when (@variationMenuVertical) { + .ui.inverted.vertical.menu .item .menu .active.item { + background: @invertedSubMenuActiveBackground; + color: @invertedSubMenuActiveColor; + } + } + & when (@variationMenuPointing) { + .ui.inverted.pointing.menu .active.item:after { + background: @invertedArrowActiveColor; + margin: 0 !important; + box-shadow: none !important; + border: none !important; + } + } + + /*--- Active Hover ---*/ + .ui.inverted.menu .active.item:hover { + background: @invertedActiveHoverBackground; + color: @invertedActiveHoverColor !important; + } + & when (@variationMenuPointing) { + .ui.inverted.pointing.menu .active.item:hover:after { + background: @invertedArrowActiveHoverColor; + } + } +} + +& when (@variationMenuFloated) { + /*-------------- + Floated + ---------------*/ + + .ui.floated.menu { + float: left; + margin: 0 @floatedDistance 0 0; + } + .ui.floated.menu .item:last-child:before { + display: none; + } + + .ui.right.floated.menu { + float: right; + margin: 0 0 0 @floatedDistance; + } +} + +& when (@variationMenuInverted) { + /*-------------- + Inverted + ---------------*/ + + each(@colors, { + @color: replace(@key, '@', ''); + @c: @colors[@@color][color]; + @h: @colors[@@color][hover]; + + & when not (@color=secondary) { + .ui.ui.ui.inverted.menu .@{color}.active.item, + .ui.ui.inverted.@{color}.menu { + background-color: @c; + } + .ui.inverted.@{color}.menu .item:before { + background-color: @invertedColoredDividerBackground; + } + .ui.ui.inverted.@{color}.menu .active.item { + background-color: @invertedColoredActiveBackground; + } + & when (@variationMenuPointing) { + .ui.inverted.pointing.@{color}.menu .active.item { + background-color: @h; + } + } + } + }) + + & when (@variationMenuPointing) { + .ui.ui.ui.inverted.pointing.menu .active.item:after { + background-color: inherit; + } + } +} + +& when (@variationMenuFitted) { + /*-------------- + Fitted + ---------------*/ + + .ui.fitted.menu .item, + .ui.fitted.menu .item .menu .item, + .ui.menu .fitted.item { + padding: 0; + } + .ui.horizontally.fitted.menu .item, + .ui.horizontally.fitted.menu .item .menu .item, + .ui.menu .horizontally.fitted.item { + padding-top: @itemVerticalPadding; + padding-bottom: @itemVerticalPadding; + } + .ui.vertically.fitted.menu .item, + .ui.vertically.fitted.menu .item .menu .item, + .ui.menu .vertically.fitted.item { + padding-left: @itemHorizontalPadding; + padding-right: @itemHorizontalPadding; + } +} + +& when (@variationMenuBorderless) { + /*-------------- + Borderless + ---------------*/ + + .ui.borderless.menu .item:before, + .ui.borderless.menu .item .menu .item:before, + .ui.menu .borderless.item:before { + background: none !important; + } +} + +& when (@variationMenuCompact) { + /*------------------- + Compact + --------------------*/ + + .ui.compact.menu { + display: inline-flex; + margin: 0; + vertical-align: middle; + } + & when (@variationMenuVertical) { + .ui.compact.vertical.menu { + /* IE hack to make dropdown icons appear inline */ + display: -ms-inline-flexbox !important; + display: inline-block; + } + } + .ui.compact.menu:not(.secondary) .item:last-child { + border-radius: 0 @borderRadius @borderRadius 0; + } + .ui.compact.menu .item:last-child:before { + display: none; + } + & when (@variationMenuVertical) { + .ui.compact.vertical.menu { + width: auto !important; + } + .ui.compact.vertical.menu .item:last-child::before { + display: block; + } + } +} + +& when (@variationMenuFluid) { + /*------------------- + Fluid + --------------------*/ + + .ui.menu.fluid, + .ui.vertical.menu.fluid { + width: 100% !important; + } +} + + +/*------------------- + Evenly Sized +--------------------*/ + +.ui.item.menu, +.ui.item.menu .item { + width: 100%; + padding-left: 0 !important; + padding-right: 0 !important; + margin-left: 0 !important; + margin-right: 0 !important; + text-align: center; + justify-content: center; +} +.ui.attached.item.menu:not(.tabular) { + margin: 0 @attachedHorizontalOffset !important; +} + +.ui.item.menu .item:last-child:before { + display: none; +} + +.ui.menu.two.item .item { + width: 50%; +} +.ui.menu.three.item .item { + width: 33.333%; +} +.ui.menu.four.item .item { + width: 25%; +} +.ui.menu.five.item .item { + width: 20%; +} +.ui.menu.six.item .item { + width: 16.666%; +} +.ui.menu.seven.item .item { + width: 14.285%; +} +.ui.menu.eight.item .item { + width: 12.500%; +} +.ui.menu.nine.item .item { + width: 11.11%; +} +.ui.menu.ten.item .item { + width: 10.0%; +} +.ui.menu.eleven.item .item { + width: 9.09%; +} +.ui.menu.twelve.item .item { + width: 8.333%; +} + +& when (@variationMenuFixed) { + /*-------------- + Fixed + ---------------*/ + + .ui.menu.fixed { + position: fixed; + z-index: 101; + margin: 0; + width: 100%; + } + .ui.menu.fixed, + .ui.menu.fixed .item:first-child, + .ui.menu.fixed .item:last-child { + border-radius: 0 !important; + } + + .ui.fixed.menu, + .ui[class*="top fixed"].menu { + top: 0; + left: 0; + right: auto; + bottom: auto; + } + .ui[class*="top fixed"].menu { + border-top: none; + border-left: none; + border-right: none; + } + .ui[class*="right fixed"].menu { + border-top: none; + border-bottom: none; + border-right: none; + top: 0; + right: 0; + left: auto; + bottom: auto; + width: auto; + height: 100%; + } + .ui[class*="bottom fixed"].menu { + border-bottom: none; + border-left: none; + border-right: none; + bottom: 0; + left: 0; + top: auto; + right: auto; + } + .ui[class*="left fixed"].menu { + border-top: none; + border-bottom: none; + border-left: none; + top: 0; + left: 0; + right: auto; + bottom: auto; + width: auto; + height: 100%; + } + + /* Coupling with Grid */ + .ui.fixed.menu + .ui.grid { + padding-top: @fixedPrecedingGridMargin; + } +} + +& when (@variationMenuPointing) { + /*------------------- + Pointing + --------------------*/ + + .ui.pointing.menu .item:after { + visibility: hidden; + position: absolute; + content: ''; + top: 100%; + left: 50%; + transform: translateX(-50%) translateY(-50%) rotate(45deg); + background: none; + + margin: (@arrowBorderWidth / 2) 0 0; + width: @arrowSize; + height: @arrowSize; + + border: none; + border-bottom: @arrowBorder; + border-right: @arrowBorder; + + z-index: @arrowZIndex; + transition: @arrowTransition; + } + & when (@variationMenuVertical) { + .ui.vertical.pointing.menu .item:after { + position: absolute; + top: 50%; + right: 0; + bottom: auto; + left: auto; + + transform: translateX(50%) translateY(-50%) rotate(45deg); + margin: 0 -(@arrowBorderWidth / 2) 0 0; + + border: none; + border-top: @arrowBorder; + border-right: @arrowBorder; + } + } + .ui.pointing.menu .ui.dropdown .menu .item:after, + .ui.vertical.pointing.menu .ui.dropdown .menu .item:after { + display: none; + } + + /* Active */ + .ui.pointing.menu .active.item:after { + visibility: visible; + } + .ui.pointing.menu .active.dropdown.item:after { + visibility: hidden; + } + + /* Don't double up pointers */ + .ui.pointing.menu .dropdown.active.item:after, + .ui.pointing.menu .active.item .menu .active.item:after { + display: none; + } + + /* Colors */ + .ui.pointing.menu .active.item:hover:after { + background-color: @arrowHoverColor; + } + .ui.pointing.menu .active.item:after { + background-color: @arrowActiveColor; + } + .ui.pointing.menu .active.item:hover:after { + background-color: @arrowActiveHoverColor; + } + & when (@variationMenuVertical) { + .ui.vertical.pointing.menu .active.item:hover:after { + background-color: @arrowVerticalHoverColor; + } + .ui.vertical.pointing.menu .active.item:after { + background-color: @arrowVerticalActiveColor; + } + .ui.vertical.pointing.menu .menu .active.item:after { + background-color: @arrowVerticalSubMenuColor; + } + } +} + +each(@colors, { + @color: replace(@key, '@', ''); + @c: @colors[@@color][color]; + + .ui.inverted.pointing.menu .@{color}.active.item:after { + background-color: @c; + } +}) + +& when (@variationMenuAttached) { + /*-------------- + Attached + ---------------*/ + + /* Middle */ + .ui.attached.menu { + top: 0; + bottom: 0; + border-radius: 0; + margin: 0 @attachedHorizontalOffset; + width: @attachedWidth; + max-width: @attachedWidth; + box-shadow: @attachedBoxShadow; + } + .ui.attached + .ui.attached.menu:not(.top) { + border-top: none; + } + + /* Top */ + .ui[class*="top attached"].menu { + bottom: 0; + margin-bottom: 0; + top: @attachedTopOffset; + margin-top: @verticalMargin; + border-radius: @borderRadius @borderRadius 0 0; + } + .ui.menu[class*="top attached"]:first-child { + margin-top: 0; + } + + /* Bottom */ + .ui[class*="bottom attached"].menu { + bottom: 0; + margin-top: 0; + top: @attachedBottomOffset; + margin-bottom: @verticalMargin; + box-shadow: @attachedBottomBoxShadow; + border-radius: 0 0 @borderRadius @borderRadius; + } + .ui[class*="bottom attached"].menu:last-child { + margin-bottom: 0; + } + + /* Attached Menu Item */ + .ui.top.attached.menu > .item:first-child { + border-radius: @borderRadius 0 0 0; + } + .ui.bottom.attached.menu > .item:first-child { + border-radius: 0 0 0 @borderRadius; + } + + /* Tabular Attached */ + .ui.attached.menu:not(.tabular) { + border: @attachedBorder; + } + & when (@variationMenuInverted) { + .ui.attached.inverted.menu { + border: none; + } + } + & when (@variationMenuTabular) { + .ui.attached.tabular.menu { + margin-left: 0; + margin-right: 0; + width: 100%; + } + } +} + +/*-------------- + Sizes +---------------*/ + +.ui.menu { + font-size: @medium; +} +.ui.vertical.menu { + width: @mediumWidth; +} +& when not (@variationMenuSizes = false) { + each(@variationMenuSizes, { + @w: @{value}Width; + @s: @@value; + .ui.@{value}.menu, + .ui.@{value}.menu .dropdown, + .ui.@{value}.menu .dropdown .menu > .item { + font-size: @s; + } + .ui.@{value}.vertical.menu:not(.icon) { + width: @@w; + } + }) +} + +/*------------------- + Inverted dropdowns +--------------------*/ +.ui.menu .ui.inverted.inverted.dropdown.item .menu { + background: @invertedDropdownBackground; + box-shadow: @invertedDropdownMenuBoxShadow; +} + +.ui.menu .ui.inverted.dropdown .menu > .item { + color: @invertedDropdownItemColor !important; +} + +.ui.menu .ui.inverted.dropdown .menu > .active.item { + background: @invertedDropdownActiveItemBackground !important; + color: @invertedDropdownActiveItemColor !important; +} + +.ui.menu .ui.inverted.dropdown .menu > .item:hover { + background: @invertedDropdownHoveredItemBackground !important; + color: @invertedDropdownHoveredItemColor !important; +} + +.ui.menu .ui.inverted.dropdown .menu > .selected.item { + background: @invertedDropdownSelectedItemBackground !important; + color: @invertedDropdownSelectedItemColor !important; +} + +& when (@variationMenuVertical) { + /* Vertical */ + .ui.vertical.menu .inverted.dropdown.item .menu { + box-shadow: @invertedDropdownMenuBoxShadow; + } +} + +.loadUIOverrides(); diff --git a/semantic/src/definitions/collections/message.less b/semantic/src/definitions/collections/message.less new file mode 100644 index 0000000..e237277 --- /dev/null +++ b/semantic/src/definitions/collections/message.less @@ -0,0 +1,414 @@ +/*! + * # Fomantic-UI - Message + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +/******************************* + Theme +*******************************/ + +@type : 'collection'; +@element : 'message'; + +@import (multiple) '../../theme.config'; + +/******************************* + Message +*******************************/ + +.ui.message { + position: relative; + min-height: 1em; + margin: @verticalMargin 0; + background: @background; + padding: @padding; + line-height: @lineHeight; + color: @textColor; + transition: @transition; + border-radius: @borderRadius; + box-shadow: @boxShadow; +} + +.ui.message:first-child { + margin-top: 0; +} +.ui.message:last-child { + margin-bottom: 0; +} + + +/*-------------- + Content +---------------*/ + +/* Header */ +.ui.message .header { + display: @headerDisplay; + font-family: @headerFont; + font-weight: @headerFontWeight; + margin: @headerMargin; +} + +/* Default font size */ +.ui.message .header:not(.ui) { + font-size: @headerFontSize; +} + +/* Paragraph */ +.ui.message p { + opacity: @messageTextOpacity; + margin: @messageParagraphMargin 0; +} +.ui.message p:first-child { + margin-top: 0; +} +.ui.message p:last-child { + margin-bottom: 0; +} +.ui.message .header + p { + margin-top: @headerParagraphDistance; +} + +/* List */ +.ui.message .list:not(.ui) { + text-align: left; + padding: 0; + opacity: @listOpacity; + list-style-position: @listStylePosition; + margin: @listMargin 0 0; +} +.ui.message .list:not(.ui):first-child { + margin-top: 0; +} +.ui.message .list:not(.ui):last-child { + margin-bottom: 0; +} +.ui.message .list:not(.ui) li { + position: relative; + list-style-type: none; + margin: 0 0 @listItemMargin @listItemIndent; + padding: 0; +} +.ui.message .list:not(.ui) li:before { + position: absolute; + content: '•'; + left: -1em; + height: 100%; + vertical-align: baseline; +} +.ui.message .list:not(.ui) li:last-child { + margin-bottom: 0; +} + + +/* Icon */ +.ui.message > i.icon { + margin-right: @iconDistance; +} + +/* Close Icon */ +.ui.message > .close.icon { + cursor: pointer; + position: absolute; + margin: 0; + top: @closeTopDistance; + right: @closeRightDistance; + opacity: @closeOpacity; + transition: @closeTransition; +} +.ui.message > .close.icon:hover { + opacity: 1; +} + +/* First / Last Element */ +.ui.message > :first-child { + margin-top: 0; +} +.ui.message > :last-child { + margin-bottom: 0; +} + +/******************************* + Coupling +*******************************/ + +.ui.dropdown .menu > .message { + margin: 0 -@borderWidth; +} + +/******************************* + States +*******************************/ + +/*-------------- + Visible +---------------*/ + +.ui.visible.visible.visible.visible.message { + display: block; +} + +.ui.icon.visible.visible.visible.visible.message { + display: flex; +} + +/*-------------- + Hidden +---------------*/ + +.ui.hidden.hidden.hidden.hidden.message { + display: none; +} + + +/******************************* + Variations +*******************************/ + +& when (@variationMessageCompact) { + /*-------------- + Compact + ---------------*/ + + .ui.compact.message { + display: inline-block; + } + .ui.compact.icon.message { + display: inline-flex; + width: auto; + } +} + +& when (@variationMessageAttached) { + /*-------------- + Attached + ---------------*/ + + .ui.attached.message { + margin-bottom: @attachedYOffset; + border-radius: @borderRadius @borderRadius 0 0; + box-shadow: @attachedBoxShadow; + margin-left: @attachedXOffset; + margin-right: @attachedXOffset; + } + .ui.attached + .ui.attached.message:not(.top):not(.bottom) { + margin-top: @attachedYOffset; + border-radius: 0; + } + .ui.bottom.attached.message { + margin-top: @attachedYOffset; + border-radius: 0 0 @borderRadius @borderRadius; + box-shadow: @attachedBottomBoxShadow; + } + .ui.bottom.attached.message:not(:last-child) { + margin-bottom: @verticalMargin; + } + & when (@variationMessageIcon) { + .ui.attached.icon.message { + width: auto; + } + } +} + +& when (@variationMessageIcon) { + /*-------------- + Icon + ---------------*/ + + .ui.icon.message { + display: flex; + width: 100%; + align-items: center; + } + .ui.icon.message > i.icon:not(.close) { + display: block; + flex: 0 0 auto; + width: auto; + line-height: 1; + vertical-align: @iconVerticalAlign; + font-size: @iconSize; + opacity: @iconOpacity; + } + .ui.icon.message > .content { + display: block; + flex: 1 1 auto; + vertical-align: @iconVerticalAlign; + } + + + .ui.icon.message > i.icon:not(.close) + .content { + padding-left: @iconContentDistance; + } + .ui.icon.message > i.circular.icon { + width: 1em; + } +} + +& when (@variationMessageFloating) { + /*-------------- + Floating + ---------------*/ + + .ui.floating.message { + box-shadow: @floatingBoxShadow; + } +} + + +/*-------------- + Colors +---------------*/ + +/*-------------- + Types +---------------*/ +& when (@variationMessageConsequences) { + + @consequences: { + @positive: { + background : @positiveBackgroundColor; + header : @positiveHeaderColor; + boxShadow : @positiveBoxShadow; + boxFloatShadow : @positiveBoxFloatingShadow; + text : @positiveTextColor; + }; + @negative: { + background : @negativeBackgroundColor; + header : @negativeHeaderColor; + boxShadow : @negativeBoxShadow; + boxFloatShadow : @negativeBoxFloatingShadow; + text : @negativeTextColor; + }; + @info: { + background : @infoBackgroundColor; + header : @infoHeaderColor; + boxShadow : @infoBoxShadow; + boxFloatShadow : @infoBoxFloatingShadow; + text : @infoTextColor; + }; + @warning: { + background : @warningBackgroundColor; + header : @warningHeaderColor; + boxShadow : @warningBoxShadow; + boxFloatShadow : @warningBoxFloatingShadow; + text : @warningTextColor; + }; + @error: { + background : @errorBackgroundColor; + header : @errorHeaderColor; + boxShadow : @errorBoxShadow; + boxFloatShadow : @errorBoxFloatingShadow; + text : @errorTextColor; + }; + @success: { + background : @successBackgroundColor; + header : @successHeaderColor; + boxShadow : @successBoxShadow; + boxFloatShadow : @successBoxFloatingShadow; + text : @successTextColor; + }; + } + + /* Colors */ + + each(@consequences, { + @color: replace(@key, '@', ''); + @bg: @consequences[@@color][background]; + @hd: @consequences[@@color][header]; + @bs: @consequences[@@color][boxShadow]; + @bfs: @consequences[@@color][boxFloatShadow]; + @t: @consequences[@@color][text]; + + .ui.@{color}.message { + background-color: @bg; + color: @t; + } + + .ui.@{color}.message, + .ui.attached.@{color}.message { + box-shadow: @bs; + } + & when (@variationMessageFloating) { + .ui.floating.@{color}.message { + box-shadow: @bfs; + } + } + .ui.@{color}.message .header { + color: @hd; + } + }) +} + +each(@colors, { + @color: replace(@key, '@', ''); + @bg: @colors[@@color][background]; + @hd: @colors[@@color][header]; + @bs: @colors[@@color][boxShadow]; + @bfs: @colors[@@color][boxFloatShadow]; + @t: @colors[@@color][text]; + @isVeryDark: @colors[@@color][isVeryDark]; + + .ui.@{color}.message { + & when not (@isVeryDark) { + background-color: @bg; + color: @t; + } + & when (@isVeryDark) { + background-color: @black; + color: @invertedTextColor; + } + } + + .ui.@{color}.message, + .ui.attached.@{color}.message { + & when not (@isVeryDark) { + box-shadow: @bs; + } + } + & when (@variationMessageFloating) { + .ui.floating.@{color}.message { + & when not (@isVeryDark) { + box-shadow: @bfs; + } + } + } + + .ui.@{color}.message .header { + & when not (@isVeryDark) { + color: @hd; + } + & when (@isVeryDark) { + color: @invertedTextColor; + } + } +}) + +& when (@variationMessageInverted) { + .ui.inverted.message { + background-color: @black; + color: @invertedTextColor; + } +} + +/*-------------- + Sizes +---------------*/ + +.ui.message { + font-size: @relativeMedium; +} +& when not (@variationMessageSizes = false) { + each(@variationMessageSizes, { + @s: @{value}MessageSize; + .ui.@{value}.message { + font-size: @@s; + } + }) +} + +.loadUIOverrides(); diff --git a/semantic/src/definitions/collections/table.less b/semantic/src/definitions/collections/table.less new file mode 100644 index 0000000..f185282 --- /dev/null +++ b/semantic/src/definitions/collections/table.less @@ -0,0 +1,1322 @@ +/*! + * # Fomantic-UI - Table + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + + +/******************************* + Theme +*******************************/ + +@type : 'collection'; +@element : 'table'; + +@import (multiple) '../../theme.config'; + +/******************************* + Table +*******************************/ + +/* Prototype */ +.ui.table { + width: 100%; + background: @background; + margin: @margin; + border: @border; + box-shadow: @boxShadow; + border-radius: @borderRadius; + text-align: @textAlign; + vertical-align: @verticalAlign; + color: @color; + border-collapse: @borderCollapse; + border-spacing: @borderSpacing; +} + +.ui.table:first-child { + margin-top: 0; +} +.ui.table:last-child { + margin-bottom: 0; +} +.ui.table > thead, +.ui.table > tbody { + text-align: inherit; + vertical-align: inherit; +} + +/******************************* + Parts +*******************************/ + +/* Table Content */ +.ui.table th, +.ui.table td { + transition: @transition; +} + +/* Rowspan helper class */ +.ui.table th.rowspanned, +.ui.table td.rowspanned { + display:none; +} + +/* Headers */ +.ui.table > thead { + box-shadow: @headerBoxShadow; +} +.ui.table > thead > tr > th { + cursor: auto; + background: @headerBackground; + text-align: @headerAlign; + color: @headerColor; + padding: @headerVerticalPadding @headerHorizontalPadding; + vertical-align: @headerVerticalAlign; + font-style: @headerFontStyle; + font-weight: @headerFontWeight; + text-transform: @headerTextTransform; + border-bottom: @headerBorder; + border-left: @headerDivider; +} + +.ui.table > thead > tr > th:first-child { + border-left: none; +} + +.ui.table > thead > tr:first-child > th:first-child { + border-radius: @borderRadius 0 0 0; +} +.ui.table > thead > tr:first-child > th:last-child { + border-radius: 0 @borderRadius 0 0; +} +.ui.table > thead > tr:first-child > th:only-child { + border-radius: @borderRadius @borderRadius 0 0; +} + +/* Footer */ +.ui.table > tfoot { + box-shadow: @footerBoxShadow; +} +.ui.table > tfoot > tr > th, +.ui.table > tfoot > tr > td { + cursor: auto; + border-top: @footerBorder; + background: @footerBackground; + text-align: @footerAlign; + color: @footerColor; + padding: @footerVerticalPadding @footerHorizontalPadding; + vertical-align: @footerVerticalAlign; + font-style: @footerFontStyle; + font-weight: @footerFontWeight; + text-transform: @footerTextTransform; +} +.ui.table > tfoot > tr > th:first-child, +.ui.table > tfoot > tr > td:first-child { + border-left: none; +} +.ui.table > tfoot > tr:first-child > th:first-child, +.ui.table > tfoot > tr:first-child > td:first-child { + border-radius: 0 0 0 @borderRadius; +} +.ui.table > tfoot > tr:first-child > th:last-child, +.ui.table > tfoot > tr:first-child > td:last-child { + border-radius: 0 0 @borderRadius 0; +} +.ui.table > tfoot > tr:first-child > th:only-child, +.ui.table > tfoot > tr:first-child > td:only-child { + border-radius: 0 0 @borderRadius @borderRadius; +} + +/* Table Row */ +.ui.table > tr > td, +.ui.table > tbody > tr > td { + border-top: @rowBorder; +} +.ui.table > tr:first-child > td, +.ui.table > tbody > tr:first-child > td { + border-top: none; +} + +/* Repeated tbody */ +.ui.table > tbody + tbody tr:first-child > td { + border-top: @rowBorder; +} + +/* Table Cells */ +.ui.table > tbody > tr > td, +.ui.table > tr > td { + padding: @cellVerticalPadding @cellHorizontalPadding; + text-align: @cellTextAlign; +} + +/* Icons */ +.ui.table > i.icon { + vertical-align: @iconVerticalAlign; +} +.ui.table > i.icon:only-child { + margin: 0; +} + +/* Table Segment */ +.ui.table.segment { + padding: 0; +} +.ui.table.segment:after { + display: none; +} +.ui.table.segment.stacked:after { + display: block; +} + + +/* Responsive */ +@media only screen and (max-width : @largestMobileScreen) { + .ui.table:not(.unstackable) { + width: 100%; + padding: 0; + } + .ui.table:not(.unstackable) > thead, + .ui.table:not(.unstackable) > thead > tr, + .ui.table:not(.unstackable) > tfoot, + .ui.table:not(.unstackable) > tfoot > tr, + .ui.table:not(.unstackable) > tbody, + .ui.table:not(.unstackable) > tr, + .ui.table:not(.unstackable) > tbody > tr, + .ui.table:not(.unstackable) > tr > th:not(.rowspanned), + .ui.table:not(.unstackable) > thead > tr > th:not(.rowspanned), + .ui.table:not(.unstackable) > tbody > tr > th:not(.rowspanned), + .ui.table:not(.unstackable) > tfoot > tr > th:not(.rowspanned), + .ui.table:not(.unstackable) > tr > td:not(.rowspanned), + .ui.table:not(.unstackable) > tbody > tr > td:not(.rowspanned), + .ui.table:not(.unstackable) > tfoot > tr > td:not(.rowspanned) { + display: block !important; + width: auto !important; + } + + .ui.table:not(.unstackable) > thead { + display: @responsiveHeaderDisplay; + } + .ui.table:not(.unstackable) > tfoot { + display: @responsiveFooterDisplay; + } + .ui.ui.ui.ui.table:not(.unstackable) > tr, + .ui.ui.ui.ui.table:not(.unstackable) > thead > tr, + .ui.ui.ui.ui.table:not(.unstackable) > tbody > tr, + .ui.ui.ui.ui.table:not(.unstackable) > tfoot > tr { + padding-top: @responsiveRowVerticalPadding; + padding-bottom: @responsiveRowVerticalPadding; + box-shadow: @responsiveRowBoxShadow; + } + + .ui.ui.ui.ui.table:not(.unstackable) > tr > th, + .ui.ui.ui.ui.table:not(.unstackable) > thead > tr > th, + .ui.ui.ui.ui.table:not(.unstackable) > tbody > tr > th, + .ui.ui.ui.ui.table:not(.unstackable) > tfoot > tr > th, + .ui.ui.ui.ui.table:not(.unstackable) > tr > td, + .ui.ui.ui.ui.table:not(.unstackable) > tbody > tr > td, + .ui.ui.ui.ui.table:not(.unstackable) > tfoot > tr > td { + background: none; + border: none; + padding: @responsiveCellVerticalPadding @responsiveCellHorizontalPadding; + box-shadow: @responsiveCellBoxShadow; + } + .ui.table:not(.unstackable) > tr > th:first-child, + .ui.table:not(.unstackable) > thead > tr > th:first-child, + .ui.table:not(.unstackable) > tbody > tr > th:first-child, + .ui.table:not(.unstackable) > tfoot > tr > th:first-child, + .ui.table:not(.unstackable) > tr > td:first-child, + .ui.table:not(.unstackable) > tbody > tr > td:first-child, + .ui.table:not(.unstackable) > tfoot > tr > td:first-child { + font-weight: @responsiveCellHeaderFontWeight; + } + + /* Definition Table */ + .ui.definition.table:not(.unstackable) > thead > tr > th:first-child { + box-shadow: none !important; + } + & when (@variationTableMarked) { + each(@colors, { + @color: replace(@key, '@', ''); + @c: @colors[@@color][color]; + @l: @colors[@@color][light]; + .ui.ui.ui.ui.table:not(.unstackable) tr.marked.@{color} { + &.left { + box-shadow: @responsiveRowBoxShadow, @coloredBorderSize 0 0 0 @c inset; + } + &.right { + box-shadow: @responsiveRowBoxShadow, -@coloredBorderSize 0 0 0 @c inset; + } + } + & when (@variationTableInverted) { + .ui.ui.ui.ui.inverted.table:not(.unstackable) tr.marked.@{color} { + &.left { + box-shadow: @responsiveRowBoxShadow, @coloredBorderSize 0 0 0 @l inset; + } + &.right { + box-shadow: @responsiveRowBoxShadow, -@coloredBorderSize 0 0 0 @l inset; + } + } + } + }) + } +} + + +/******************************* + Coupling +*******************************/ + +/* UI Image */ +.ui.table .collapsing .image, +.ui.table .collapsing .image img { + max-width: none; +} + + +/******************************* + Types +*******************************/ + +/*-------------- + Complex +---------------*/ +& when (@variationTableStructured) { + .ui.structured.table { + border-collapse: collapse; + } + .ui.structured.table > thead > tr > th { + border-left: @headerDivider; + border-right: @headerDivider; + } + & when (@variationTableSortable) { + .ui.structured.sortable.table > thead > tr > th { + border-left: @sortableBorder; + border-right: @sortableBorder; + } + } + & when (@variationTableBasic) { + .ui.structured.basic.table > tr > th, + .ui.structured.basic.table > thead > tr > th, + .ui.structured.basic.table > tbody > tr > th, + .ui.structured.basic.table > tfoot > tr > th { + border-left: @basicTableHeaderDivider; + border-right: @basicTableHeaderDivider; + } + } + & when (@variationTableCelled) { + .ui.structured.celled.table > tr > th, + .ui.structured.celled.table > thead > tr > th, + .ui.structured.celled.table > tbody > tr > th, + .ui.structured.celled.table > tfoot > tr > th, + .ui.structured.celled.table > tr > td, + .ui.structured.celled.table > tbody > tr > td , + .ui.structured.celled.table > tfoot > tr > td { border-left: @cellBorder; + border-right: @cellBorder; + } + } +} + +& when (@variationTableDefinition) { + /*-------------- + Definition + ---------------*/ + + .ui.definition.table > thead:not(.full-width) > tr > th:first-child { + pointer-events: none; + background: @definitionHeaderBackground; + font-weight: @definitionHeaderFontWeight; + color: @definitionHeaderColor; + box-shadow: -@coloredBorderSizeCover -@coloredBorderSize 0 @coloredBorderSizeCover @definitionPageBackground; + -moz-transform: scale(1); + } + + .ui.definition.table > tfoot:not(.full-width) > tr > th:first-child { + pointer-events: none; + background: @definitionFooterBackground; + font-weight: @definitionFooterFontWeight; + color: @definitionFooterColor; + box-shadow: -@coloredBorderSizeCover @coloredBorderSize 0 @coloredBorderSizeCover @definitionPageBackground; + -moz-transform: scale(1); + } + + /* Highlight Defining Column */ + .ui.definition.table > tr > td:first-child:not(.ignored), + .ui.definition.table > tbody > tr > td:first-child:not(.ignored), + .ui.definition.table > tfoot > tr > td:first-child:not(.ignored), + .ui.definition.table tr td.definition { + background: @definitionColumnBackground; + font-weight: @definitionColumnFontWeight; + color: @definitionColumnColor; + text-transform: @definitionColumnTextTransform; + box-shadow: @definitionColumnBoxShadow; + text-align: @definitionColumnTextAlign; + font-size: @definitionColumnFontSize; + padding-left: @definitionColumnHorizontalPadding; + padding-right: @definitionColumnHorizontalPadding; + } + + + /* Fix 2nd Column */ + .ui.definition.table > thead:not(.full-width) > tr > th:nth-child(2) { + border-left: @borderWidth solid @borderColor; + } + .ui.definition.table > tfoot:not(.full-width) > tr > th:nth-child(2) , + .ui.definition.table > tfoot:not(.full-width) > tr > td:nth-child(2) { border-left: @borderWidth solid @borderColor; + } + .ui.definition.table > tr > td:nth-child(2), + .ui.definition.table > tbody > tr > td:nth-child(2) { + border-left: @borderWidth solid @borderColor; + } +} + +/******************************* + States +*******************************/ + +& when (@variationTablePositive) { + /*-------------- + Positive + ---------------*/ + + .ui.ui.ui.ui.table tr.positive, + .ui.ui.table td.positive { + box-shadow: @positiveBoxShadow; + background: @positiveBackgroundColor; + color: @positiveColor; + } +} + +& when (@variationTableNegative) { + /*-------------- + Negative + ---------------*/ + + .ui.ui.ui.ui.table tr.negative, + .ui.ui.table td.negative { + box-shadow: @negativeBoxShadow; + background: @negativeBackgroundColor; + color: @negativeColor; + } +} + +& when (@variationTableError) { + /*-------------- + Error + ---------------*/ + + .ui.ui.ui.ui.table tr.error, + .ui.ui.table td.error { + box-shadow: @errorBoxShadow; + background: @errorBackgroundColor; + color: @errorColor; + } +} + +& when (@variationTableWarning) { + /*-------------- + Warning + ---------------*/ + + .ui.ui.ui.ui.table tr.warning, + .ui.ui.table td.warning { + box-shadow: @warningBoxShadow; + background: @warningBackgroundColor; + color: @warningColor; + } +} + +& when (@variationTableActive) { + /*-------------- + Active + ---------------*/ + + .ui.ui.ui.ui.table tr.active, + .ui.ui.table td.active { + box-shadow: @activeBoxShadow; + background: @activeBackgroundColor; + color: @activeColor; + } +} + + +& when (@variationTableDisabled) { + /*-------------- + Disabled + ---------------*/ + + .ui.table tr.disabled td, + .ui.table tr td.disabled, + .ui.table tr.disabled:hover, + .ui.table tr:hover td.disabled { + pointer-events: none; + color: @disabledTextColor; + } +} + +/******************************* + Variations +*******************************/ +& when (@variationTableStackable) { + /*-------------- + Stackable + ---------------*/ + + @media only screen and (max-width : @largestTabletScreen) { + + .ui[class*="tablet stackable"].table, + .ui[class*="tablet stackable"].table > thead, + .ui[class*="tablet stackable"].table > thead > tr, + .ui[class*="tablet stackable"].table > tfoot, + .ui[class*="tablet stackable"].table > tfoot > tr, + .ui[class*="tablet stackable"].table > tbody, + .ui[class*="tablet stackable"].table > tbody > tr, + .ui[class*="tablet stackable"].table > tr, + .ui[class*="tablet stackable"].table > thead > tr > th:not(.rowspanned), + .ui[class*="tablet stackable"].table > tbody > tr > th:not(.rowspanned), + .ui[class*="tablet stackable"].table > tfoot > tr > th:not(.rowspanned), + .ui[class*="tablet stackable"].table > tr > th:not(.rowspanned), + .ui[class*="tablet stackable"].table > tbody > tr > td:not(.rowspanned), + .ui[class*="tablet stackable"].table > tfoot > tr > td:not(.rowspanned), + .ui[class*="tablet stackable"].table > tr > td:not(.rowspanned) { + display: block !important; + width: 100% !important; + } + + .ui[class*="tablet stackable"].table { + padding: 0; + } + .ui[class*="tablet stackable"].table > thead { + display: @responsiveHeaderDisplay; + } + .ui[class*="tablet stackable"].table > tfoot { + display: @responsiveFooterDisplay; + } + .ui.ui.ui.ui[class*="tablet stackable"].table > thead > tr, + .ui.ui.ui.ui[class*="tablet stackable"].table > tbody > tr, + .ui.ui.ui.ui[class*="tablet stackable"].table > tfoot > tr, + .ui.ui.ui.ui[class*="tablet stackable"].table > tr { + padding-top: @responsiveRowVerticalPadding; + padding-bottom: @responsiveRowVerticalPadding; + box-shadow: @responsiveRowBoxShadow; + } + .ui[class*="tablet stackable"].table > thead > tr > th, + .ui[class*="tablet stackable"].table > tbody > tr > th, + .ui[class*="tablet stackable"].table > tfoot > tr > th, + .ui[class*="tablet stackable"].table > tr > th, + .ui[class*="tablet stackable"].table > tbody > tr > td, + .ui[class*="tablet stackable"].table > tfoot > tr > td, + .ui[class*="tablet stackable"].table > tr > td { + background: none; + border: none !important; + padding: @responsiveCellVerticalPadding @responsiveCellHorizontalPadding; + box-shadow: @responsiveCellBoxShadow; + } + & when (@variationTableDefinition) { + /* Definition Table */ + .ui.definition[class*="tablet stackable"].table > thead > tr > th:first-child { + box-shadow: none !important; + } + } + } + & when (@variationTableMarked) { + each(@colors, { + @color: replace(@key, '@', ''); + @c: @colors[@@color][color]; + @l: @colors[@@color][light]; + .ui.ui.ui.ui[class*="tablet stackable"].table tr.marked.@{color} { + &.left { + box-shadow: @responsiveRowBoxShadow, @coloredBorderSize 0 0 0 @c inset; + } + &.right { + box-shadow: @responsiveRowBoxShadow, -@coloredBorderSize 0 0 0 @c inset; + } + } + & when (@variationTableInverted) { + .ui.ui.ui.ui[class*="tablet stackable"].inverted.table tr.marked.@{color} { + &.left { + box-shadow: @responsiveRowBoxShadow, @coloredBorderSize 0 0 0 @l inset; + } + &.right { + box-shadow: @responsiveRowBoxShadow, -@coloredBorderSize 0 0 0 @l inset; + } + } + } + }) + } +} + +& when (@variationTableAligned) { + /*-------------- + Text Alignment + ---------------*/ + + .ui.table[class*="left aligned"], + .ui.table [class*="left aligned"] { + text-align: left; + } + .ui.table[class*="center aligned"], + .ui.table [class*="center aligned"] { + text-align: center; + } + .ui.table[class*="right aligned"], + .ui.table [class*="right aligned"] { + text-align: right; + } + + /*------------------ + Vertical Alignment + ------------------*/ + + .ui.table[class*="top aligned"], + .ui.table [class*="top aligned"] { + vertical-align: top; + } + .ui.table[class*="middle aligned"], + .ui.table [class*="middle aligned"] { + vertical-align: middle; + } + .ui.table[class*="bottom aligned"], + .ui.table [class*="bottom aligned"] { + vertical-align: bottom; + } +} + +& when (@variationTableCollapsing) { + /*-------------- + Collapsing + ---------------*/ + + .ui.table th.collapsing, + .ui.table td.collapsing { + width: 1px; + white-space: nowrap; + } +} + +& when (@variationTableFixed) { + /*-------------- + Fixed + ---------------*/ + + .ui.fixed.table { + table-layout: fixed; + } + + .ui.fixed.table th, + .ui.fixed.table td { + overflow: hidden; + text-overflow: ellipsis; + } +} + + +& when (@variationTableSelectable) { + /*-------------- + Selectable + ---------------*/ + + .ui.ui.selectable.table > tbody > tr:hover, + .ui.table tbody tr td.selectable:hover { + background: @selectableBackground; + color: @selectableTextColor; + } + & when (@variationTableInverted) { + .ui.ui.selectable.inverted.table > tbody > tr:hover, + .ui.inverted.table tbody tr td.selectable:hover { + background: @selectableInvertedBackground; + color: @selectableInvertedTextColor; + } + } + /* Selectable Cell Link */ + .ui.table tbody tr td.selectable { + padding: 0; + } + .ui.table tbody tr td.selectable > a:not(.ui) { + display: block; + color: inherit; + padding: @cellVerticalPadding @cellHorizontalPadding; + } + .ui.table > tr > td.selectable, + .ui.table > tbody > tr > td.selectable, + .ui.selectable.table > tbody > tr, + .ui.selectable.table > tr { + cursor:pointer; + } + & when (@variationTableError) { + /* Other States */ + .ui.ui.selectable.table tr.error:hover, + .ui.table tr td.selectable.error:hover, + .ui.selectable.table tr:hover td.error { + background: @errorBackgroundHover; + color: @errorColorHover; + } + } + & when (@variationTableWarning) { + .ui.ui.selectable.table tr.warning:hover, + .ui.table tr td.selectable.warning:hover, + .ui.selectable.table tr:hover td.warning { + background: @warningBackgroundHover; + color: @warningColorHover; + } + } + & when (@variationTableActive) { + .ui.ui.selectable.table tr.active:hover, + .ui.table tr td.selectable.active:hover, + .ui.selectable.table tr:hover td.active { + background: @activeBackgroundColor; + color: @activeColor; + } + } + & when (@variationTablePositive) { + .ui.ui.selectable.table tr.positive:hover, + .ui.table tr td.selectable.positive:hover, + .ui.selectable.table tr:hover td.positive { + background: @positiveBackgroundHover; + color: @positiveColorHover; + } + } + & when (@variationTableNegative) { + .ui.ui.selectable.table tr.negative:hover, + .ui.table tr td.selectable.negative:hover, + .ui.selectable.table tr:hover td.negative { + background: @negativeBackgroundHover; + color: @negativeColorHover; + } + } +} + + +& when (@variationTableAttached) { + /*------------------- + Attached + --------------------*/ + + /* Middle */ + .ui.attached.table { + top: 0; + bottom: 0; + border-radius: 0; + margin: 0 @attachedHorizontalOffset; + width: @attachedWidth; + max-width: @attachedWidth; + box-shadow: @attachedBoxShadow; + border: @attachedBorder; + } + .ui.attached + .ui.attached.table:not(.top) { + border-top: none; + } + + /* Top */ + .ui[class*="top attached"].table { + bottom: 0; + margin-bottom: 0; + top: @attachedTopOffset; + margin-top: @verticalMargin; + border-radius: @borderRadius @borderRadius 0 0; + } + .ui.table[class*="top attached"]:first-child { + margin-top: 0; + } + + /* Bottom */ + .ui[class*="bottom attached"].table { + bottom: 0; + margin-top: 0; + top: @attachedBottomOffset; + margin-bottom: @verticalMargin; + box-shadow: @attachedBottomBoxShadow; + border-radius: 0 0 @borderRadius @borderRadius; + } + .ui[class*="bottom attached"].table:last-child { + margin-bottom: 0; + } +} + +& when (@variationTableStriped) { + /*-------------- + Striped + ---------------*/ + + /* Table Striping */ + .ui.striped.table > tr:nth-child(2n), + .ui.striped.table > tbody > tr:nth-child(2n) { + background-color: @stripedBackground; + } + & when (@variationTableInverted) { + /* Stripes */ + .ui.inverted.striped.table > tr:nth-child(2n), + .ui.inverted.striped.table > tbody > tr:nth-child(2n) { + background-color: @invertedStripedBackground; + } + } + & when (@variationTableSelectable) { + /* Allow striped active hover */ + .ui.striped.selectable.selectable.selectable.table tbody tr.active:hover { + background: @activeBackgroundHover; + color: @activeColorHover; + } + } +} + +/*-------------- + Single Line +---------------*/ + +.ui.table[class*="single line"], +.ui.table [class*="single line"] { + white-space: nowrap; +} + +/*------------------- + Colors +--------------------*/ + +each(@colors, { + @color: replace(@key, '@', ''); + @c: @colors[@@color][color]; + @t: @colors[@@color][text]; + @ht: @colors[@@color][hoverText]; + @l: @colors[@@color][light]; + @lh: @colors[@@color][lightHover]; + @r: @colors[@@color][ribbon]; + @b: @colors[@@color][bright]; + @bh: @colors[@@color][brightHover]; + @isDark: @colors[@@color][isDark]; + @isVeryDark: @colors[@@color][isVeryDark]; + + .ui.@{color}.table { + border-top: @coloredBorderSize solid @c; + } + & when (@variationTableInverted) { + .ui.inverted.@{color}.table { + background-color: @c; + color: @white; + } + } + .ui.ui.ui.ui.table tr.@{color}:not(.marked), + .ui.ui.table td.@{color}:not(.marked) { + & when (@stateMarkerWidth > 0) { + box-shadow: @stateMarkerWidth 0 0 @r inset; + } + & when (@isDark) { + background: @l; + } + & when not (@isDark) { + background: @b; + } + & when (@isVeryDark) { + color: @white; + } + & when not (@isVeryDark) { + color: @t; + } + } + & when (@variationTableSelectable) { + .ui.ui.selectable.table tr.@{color}:not(.marked):hover, + .ui.table tr td.selectable.@{color}:not(.marked):hover, + .ui.selectable.table tr:hover td.@{color}:not(.marked) { + & when (@isDark) { + background: @lh; + } + & when not (@isDark) { + background: @bh; + } + & when (@isVeryDark) { + color: @white; + } + & when not (@isVeryDark) { + color: @ht; + } + } + } + & when (@variationTableMarked) { + .ui.table td.marked.@{color}, + .ui.table tr.marked.@{color} { + &.left { + box-shadow: @coloredBorderSize 0 0 0 @c inset; + } + &.right { + box-shadow: -@coloredBorderSize 0 0 0 @c inset; + } + } + & when (@variationTableInverted) { + .ui.inverted.table td.marked.@{color}, + .ui.inverted.table tr.marked.@{color} { + &.left { + box-shadow: @coloredBorderSize 0 0 0 @l inset; + } + &.right { + box-shadow: -@coloredBorderSize 0 0 0 @l inset; + } + } + } + } + +}) + +/*-------------- + Column Count +---------------*/ + +/* Grid Based */ +.ui.one.column.table td { + width: @oneColumn; +} +.ui.two.column.table td { + width: @twoColumn; +} +.ui.three.column.table td { + width: @threeColumn; +} +.ui.four.column.table td { + width: @fourColumn; +} +.ui.five.column.table td { + width: @fiveColumn; +} +.ui.six.column.table td { + width: @sixColumn; +} +.ui.seven.column.table td { + width: @sevenColumn; +} +.ui.eight.column.table td { + width: @eightColumn; +} +.ui.nine.column.table td { + width: @nineColumn; +} +.ui.ten.column.table td { + width: @tenColumn; +} +.ui.eleven.column.table td { + width: @elevenColumn; +} +.ui.twelve.column.table td { + width: @twelveColumn; +} +.ui.thirteen.column.table td { + width: @thirteenColumn; +} +.ui.fourteen.column.table td { + width: @fourteenColumn; +} +.ui.fifteen.column.table td { + width: @fifteenColumn; +} +.ui.sixteen.column.table td { + width: @sixteenColumn; +} + +/* Column Width */ +.ui.table th.one.wide, +.ui.table td.one.wide { + width: @oneWide; +} +.ui.table th.two.wide, +.ui.table td.two.wide { + width: @twoWide; +} +.ui.table th.three.wide, +.ui.table td.three.wide { + width: @threeWide; +} +.ui.table th.four.wide, +.ui.table td.four.wide { + width: @fourWide; +} +.ui.table th.five.wide, +.ui.table td.five.wide { + width: @fiveWide; +} +.ui.table th.six.wide, +.ui.table td.six.wide { + width: @sixWide; +} +.ui.table th.seven.wide, +.ui.table td.seven.wide { + width: @sevenWide; +} +.ui.table th.eight.wide, +.ui.table td.eight.wide { + width: @eightWide; +} +.ui.table th.nine.wide, +.ui.table td.nine.wide { + width: @nineWide; +} +.ui.table th.ten.wide, +.ui.table td.ten.wide { + width: @tenWide; +} +.ui.table th.eleven.wide, +.ui.table td.eleven.wide { + width: @elevenWide; +} +.ui.table th.twelve.wide, +.ui.table td.twelve.wide { + width: @twelveWide; +} +.ui.table th.thirteen.wide, +.ui.table td.thirteen.wide { + width: @thirteenWide; +} +.ui.table th.fourteen.wide, +.ui.table td.fourteen.wide { + width: @fourteenWide; +} +.ui.table th.fifteen.wide, +.ui.table td.fifteen.wide { + width: @fifteenWide; +} +.ui.table th.sixteen.wide, +.ui.table td.sixteen.wide { + width: @sixteenWide; +} + +& when (@variationTableSortable) { + /*-------------- + Sortable + ---------------*/ + + .ui.sortable.table > thead > tr > th { + cursor: pointer; + white-space: nowrap; + border-left: @sortableBorder; + color: @sortableColor; + } + .ui.sortable.table > thead > tr > th:first-child { + border-left: none; + } + .ui.sortable.table thead th.sorted, + .ui.sortable.table thead th.sorted:hover { + user-select: none; + } + + .ui.sortable.table > thead > tr > th:after { + display: none; + font-style: normal; + font-weight: @normal; + text-decoration: inherit; + content: ''; + height: 1em; + width: @sortableIconWidth; + opacity: @sortableIconOpacity; + margin: 0 0 0 @sortableIconDistance; + font-family: @sortableIconFont; + } + .ui.sortable.table thead th.ascending:after { + content: @sortableIconAscending; + } + .ui.sortable.table thead th.descending:after { + content: @sortableIconDescending; + } + + /* Hover */ + .ui.sortable.table th.disabled:hover { + cursor: auto; + color: @sortableDisabledColor; + } + .ui.sortable.table > thead > tr > th:hover { + color: @sortableHoverColor; + } + .ui.sortable.table:not(.basic) > thead > tr > th:hover { + background: @sortableHoverBackground; + } + + /* Sorted */ + .ui.sortable.table thead th.sorted { + color: @sortableActiveColor; + } + .ui.sortable.table:not(.basic) thead th.sorted { + background: @sortableActiveBackground; + } + .ui.sortable.table thead th.sorted:after { + display: inline-block; + } + + /* Sorted Hover */ + .ui.sortable.table thead th.sorted:hover { + color: @sortableActiveHoverColor; + } + .ui.sortable.table:not(.basic) thead th.sorted:hover { + background: @sortableActiveHoverBackground; + } + & when (@variationTableInverted) { + /* Inverted */ + .ui.inverted.sortable.table thead th.sorted { + color: @sortableInvertedActiveColor; + } + .ui.inverted.sortable.table:not(.basic) thead th.sorted { + background: @sortableInvertedActiveBackground; + } + .ui.inverted.sortable.table > thead > tr > th:hover { + color: @sortableInvertedHoverColor; + } + .ui.inverted.sortable.table:not(.basic) > thead > tr > th:hover { + background: @sortableInvertedHoverBackground; + } + .ui.inverted.sortable.table:not(.basic) > thead > tr > th { + border-left-color: @sortableInvertedBorderColor; + border-right-color: @sortableInvertedBorderColor; + } + } +} + +& when (@variationTableInverted) { + /*-------------- + Inverted + ---------------*/ + + /* Text Color */ + .ui.inverted.table { + background: @invertedBackground; + color: @invertedCellColor; + border: @invertedBorder; + } + .ui.ui.inverted.table > thead > tr > th, + .ui.ui.inverted.table > tbody > tr > th, + .ui.ui.inverted.table > tfoot > tr > th, + .ui.ui.inverted.table > tfoot > tr > td, + .ui.ui.inverted.table > tr > th { + background-color: @invertedHeaderBackground; + border-color: @invertedHeaderBorderColor; + color: @invertedHeaderColor; + } + .ui.inverted.table > tbody > tr > td, + .ui.inverted.table > tfoot > tr > td, + .ui.inverted.table > tr > td { + border-color: @invertedCellBorderColor; + } + + .ui.inverted.table tr.disabled td, + .ui.inverted.table tr td.disabled, + .ui.inverted.table tr.disabled:hover td, + .ui.inverted.table tr:hover td.disabled { + pointer-events: none; + color: @invertedDisabledTextColor; + } + .ui.inverted.table tr td.disabled:not([class="disabled"]), + .ui.inverted.table tr.disabled:not([class="disabled"]) td, + .ui.inverted.table tr.disabled td[class]:not(.disabled), + .ui.inverted.table tr:hover td.disabled:not([class="disabled"]) { + color: @disabledTextColor; + } + & when (@variationTableDefinition) { + /* Definition */ + .ui.inverted.definition.table > tfoot:not(.full-width) > tr > th:first-child, + .ui.inverted.definition.table > thead:not(.full-width) > tr > th:first-child { + background: @definitionPageBackground; + } + .ui.inverted.definition.table > tbody > tr > td:first-child + .ui.inverted.definition.table > tfoot > tr > td:first-child, + .ui.inverted.definition.table > tr > td:first-child { + background: @invertedDefinitionColumnBackground; + color: @invertedDefinitionColumnColor; + } + } +} + +& when (@variationTableCollapsing) { + /*-------------- + Collapsing + ---------------*/ + + .ui.collapsing.table { + width: auto; + } +} + +& when (@variationTableBasic) { + /*-------------- + Basic + ---------------*/ + + .ui.basic.table { + background: @basicTableBackground; + border: @basicTableBorder; + box-shadow: @basicBoxShadow; + } + .ui.basic.table > thead, + .ui.basic.table > tfoot { + box-shadow: none; + } + .ui.basic.table > thead > tr > th, + .ui.basic.table > tbody > tr > th, + .ui.basic.table > tfoot > tr > th, + .ui.basic.table > tr > th { + background: @basicTableHeaderBackground; + border-left: @basicTableHeaderDivider; + } + .ui.basic.table > tbody > tr { + border-bottom: @basicTableCellBorder; + } + .ui.basic.table > tbody > tr > td, + .ui.basic.table > tfoot > tr > td, + .ui.basic.table >tr > td { + background: @basicTableCellBackground; + } + & when (@variationTableStriped) { + .ui.basic.striped.table > tbody > tr:nth-child(2n) { + background-color: @basicTableStripedBackground; + } + } + /* Very Basic */ + .ui[class*="very basic"].table { + border: none; + } + .ui[class*="very basic"].table:not(.sortable):not(.striped) > tr > th, + .ui[class*="very basic"].table:not(.sortable):not(.striped) > thead > tr > th, + .ui[class*="very basic"].table:not(.sortable):not(.striped) > tbody > tr > th, + .ui[class*="very basic"].table:not(.sortable):not(.striped) > tfoot > tr > th, + .ui[class*="very basic"].table:not(.sortable):not(.striped) > tr > td, + .ui[class*="very basic"].table:not(.sortable):not(.striped) > tbody > tr > td { + padding: @basicTableCellPadding; + } + .ui[class*="very basic"].table:not(.sortable):not(.striped) > tr > th:first-child, + .ui[class*="very basic"].table:not(.sortable):not(.striped) > thead > tr > th:first-child, + .ui[class*="very basic"].table:not(.sortable):not(.striped) > tbody > tr > th:first-child, + .ui[class*="very basic"].table:not(.sortable):not(.striped) > tfoot > tr > th:first-child, + .ui[class*="very basic"].table:not(.sortable):not(.striped) > tr > td:first-child, + .ui[class*="very basic"].table:not(.sortable):not(.striped) > tbody > tr > td:first-child , + .ui[class*="very basic"].table:not(.sortable):not(.striped) > tfoot > tr > td:first-child { + padding-left: 0; + } + .ui[class*="very basic"].table:not(.sortable):not(.striped) > tr > th:last-child, + .ui[class*="very basic"].table:not(.sortable):not(.striped) > thead > tr > th:last-child, + .ui[class*="very basic"].table:not(.sortable):not(.striped) > tbody > tr > th:last-child, + .ui[class*="very basic"].table:not(.sortable):not(.striped) > tfoot > tr > th:last-child, + .ui[class*="very basic"].table:not(.sortable):not(.striped) > tr > td:last-child, + .ui[class*="very basic"].table:not(.sortable):not(.striped) > tbody > tr > td:last-child, + .ui[class*="very basic"].table:not(.sortable):not(.striped) > tfoot >tr > td:last-child { + padding-right: 0; + } + .ui[class*="very basic"].table:not(.sortable):not(.striped) > thead > tr:first-child > th { + padding-top: 0; + } +} + +& when (@variationTableCelled) { + /*-------------- + Celled + ---------------*/ + + .ui.celled.table > tr > th, + .ui.celled.table > thead > tr > th, + .ui.celled.table > tbody > tr > th, + .ui.celled.table > tfoot > tr > th, + .ui.celled.table > tr > td, + .ui.celled.table > tbody > tr > td , + .ui.celled.table > tfoot > tr > td { + border-left: @cellBorder; + } + & when (@variationTableInverted) { + .ui.inverted.celled.table > tbody > tr > td, + .ui.inverted.celled.table > tr > td { + border-left: @invertedCellBorder; + } + } + .ui.celled.table > tr > th:first-child, + .ui.celled.table > thead > tr > th:first-child, + .ui.celled.table > tbody > tr > th:first-child, + .ui.celled.table > tfoot > tr > th:first-child, + .ui.celled.table > tr > td:first-child, + .ui.celled.table > tbody > tr > td:first-child, + .ui.celled.table > tfoot >tr > td:first-child { + border-left: none; + } +} + +& when (@variationTablePadded) { + /*-------------- + Padded + ---------------*/ + + .ui.padded.table > tr > th, + .ui.padded.table > thead > tr > th, + .ui.padded.table > tbody > tr > th, + .ui.padded.table > tfoot > tr > th { + padding-left: @paddedHorizontalPadding; + padding-right: @paddedHorizontalPadding; + } + .ui.padded.table > tr > th, + .ui.padded.table > thead > tr > th, + .ui.padded.table > tbody > tr > th, + .ui.padded.table > tfoot > tr > th, + .ui.padded.table > tr > td, + .ui.padded.table > tbody > tr > td , + .ui.padded.table > tfoot > tr > td { + padding: @paddedVerticalPadding @paddedHorizontalPadding; + } + + /* Very */ + .ui[class*="very padded"].table > tr > th, + .ui[class*="very padded"].table > thead > tr > th, + .ui[class*="very padded"].table > tbody > tr > th, + .ui[class*="very padded"].table > tfoot > tr > th { + padding-left: @veryPaddedHorizontalPadding; + padding-right: @veryPaddedHorizontalPadding; + } + .ui[class*="very padded"].table > tr > td, + .ui[class*="very padded"].table > tbody > tr > td , + .ui[class*="very padded"].table > tfoot > tr > td { + padding: @veryPaddedVerticalPadding @veryPaddedHorizontalPadding; + } +} + +& when (@variationTableCompact) { + /*-------------- + Compact + ---------------*/ + + .ui.compact.table > tr > th, + .ui.compact.table > thead > tr > th, + .ui.compact.table > tbody > tr > th, + .ui.compact.table > tfoot > tr > th { + padding-left: @compactHorizontalPadding; + padding-right: @compactHorizontalPadding; + } + .ui.compact.table > tr > td, + .ui.compact.table > tbody > tr > td , + .ui.compact.table > tfoot > tr > td { + padding: @compactVerticalPadding @compactHorizontalPadding; + } + + /* Very */ + .ui[class*="very compact"].table > tr > th, + .ui[class*="very compact"].table > thead > tr > th, + .ui[class*="very compact"].table > tbody > tr > th, + .ui[class*="very compact"].table > tfoot > tr > th { + padding-left: @veryCompactHorizontalPadding; + padding-right: @veryCompactHorizontalPadding; + } + .ui[class*="very compact"].table > tr > td, + .ui[class*="very compact"].table > tbody > tr > td , + .ui[class*="very compact"].table > tfoot > tr > td { + padding: @veryCompactVerticalPadding @veryCompactHorizontalPadding; + } +} + +/*-------------- + Sizes +---------------*/ + +/* Standard */ +.ui.table { + font-size: @medium; +} +& when not (@variationTableSizes = false) { + each(@variationTableSizes, { + @s: @@value; + .ui.@{value}.table { + font-size: @s; + } + }) +} + + +.loadUIOverrides(); diff --git a/semantic/src/definitions/elements/button.less b/semantic/src/definitions/elements/button.less new file mode 100644 index 0000000..3e648a5 --- /dev/null +++ b/semantic/src/definitions/elements/button.less @@ -0,0 +1,1881 @@ +/*! + * # Fomantic-UI - Button + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +/******************************* + Theme +*******************************/ + +@type : 'element'; +@element : 'button'; + +@import (multiple) '../../theme.config'; + +/******************************* + Button +*******************************/ + +.ui.button { + cursor: pointer; + display: inline-block; + + min-height: 1em; + + outline: none; + border: none; + vertical-align: @verticalAlign; + background: @background; + color: @textColor; + + font-family: @fontFamily; + + margin: 0 @horizontalMargin @verticalMargin 0; + padding: @verticalPadding @horizontalPadding (@verticalPadding + @shadowOffset); + + text-transform: @textTransform; + text-shadow: @textShadow; + font-weight: @fontWeight; + line-height: @lineHeight; + font-style: normal; + text-align: center; + text-decoration: none; + + border-radius: @borderRadius; + box-shadow: @boxShadow; + + user-select: none; + transition: @transition; + will-change: @willChange; + + -webkit-tap-highlight-color: @tapColor; +} + + +/******************************* + States +*******************************/ + +/*-------------- + Hover +---------------*/ + +.ui.button:hover { + background-color: @hoverBackgroundColor; + background-image: @hoverBackgroundImage; + box-shadow: @hoverBoxShadow; + color: @hoverColor; +} + +.ui.button:hover .icon { + opacity: @iconHoverOpacity; +} + +/*-------------- + Focus +---------------*/ + +.ui.button:focus { + background-color: @focusBackgroundColor; + color: @focusColor; + background-image: @focusBackgroundImage; + box-shadow: @focusBoxShadow; +} + +.ui.button:focus .icon { + opacity: @iconFocusOpacity; +} + +/*-------------- + Down +---------------*/ + +.ui.button:active, +.ui.active.button:active { + background-color: @downBackgroundColor; + background-image: @downBackgroundImage; + color: @downColor; + box-shadow: @downBoxShadow; +} + +/*-------------- + Active +---------------*/ + +.ui.active.button { + background-color: @activeBackgroundColor; + background-image: @activeBackgroundImage; + box-shadow: @activeBoxShadow; + color: @activeColor; +} +.ui.active.button:hover { + background-color: @activeHoverBackgroundColor; + background-image: @activeHoverBackgroundImage; + color: @activeHoverColor; +} +.ui.active.button:active { + background-color: @activeBackgroundColor; + background-image: @activeBackgroundImage; +} + + +/*-------------- + Loading +---------------*/ + +/* Specificity hack */ +.ui.loading.loading.loading.loading.loading.loading.button { + position: relative; + cursor: default; + text-shadow: none !important; + color: transparent; + opacity: @loadingOpacity; + pointer-events: @loadingPointerEvents; + transition: @loadingTransition; +} +.ui.loading.button:before { + position: absolute; + content: ''; + top: 50%; + left: 50%; + + margin: @loaderMargin; + width: @loaderSize; + height: @loaderSize; + + border-radius: @circularRadius; + border: @loaderLineWidth solid @invertedLoaderFillColor; +} +.ui.loading.button:after { + position: absolute; + content: ''; + top: 50%; + left: 50%; + + margin: @loaderMargin; + width: @loaderSize; + height: @loaderSize; + + border-radius: @circularRadius; + + animation: loader @loaderSpeed infinite linear; + border: @loaderLineWidth solid currentColor; + color: @invertedLoaderLineColor; + + box-shadow: 0 0 0 1px transparent; +} +& when (@variationButtonLabeledIcon){ + .ui.labeled.icon.loading.button .icon { + background-color: transparent; + box-shadow: none; + } +} +& when (@variationButtonBasic){ + .ui.basic.loading.button:not(.inverted):before { + border-color: @loaderFillColor; + } + .ui.basic.loading.button:not(.inverted):after { + border-color: @loaderLineColor; + } +} +& when (@variationButtonDisabled){ + /*------------------- + Disabled + --------------------*/ + + .ui.buttons .disabled.button:not(.basic), + .ui.disabled.button, + .ui.button:disabled, + .ui.disabled.button:hover, + .ui.disabled.active.button { + cursor: default; + opacity: @disabledOpacity !important; + background-image: none; + box-shadow: none; + pointer-events: none !important; + } + & when (@variationButtonBasic){ + /* Basic Group With Disabled */ + .ui.basic.buttons .ui.disabled.button { + border-color: @disabledBorderColor; + } + } +} + +/******************************* + Types +*******************************/ +& when (@variationButtonAnimated){ + /*------------------- + Animated + --------------------*/ + + .ui.animated.button { + position: relative; + overflow: hidden; + padding-right: 0 !important; + vertical-align: @animatedVerticalAlign; + z-index: @animatedZIndex; + } + + .ui.animated.button .content { + will-change: transform, opacity; + } + .ui.animated.button .visible.content { + position: relative; + margin-right: @horizontalPadding; + } + .ui.animated.button .hidden.content { + position: absolute; + width: 100%; + } + + /* Horizontal */ + .ui.animated.button .visible.content, + .ui.animated.button .hidden.content { + transition: right @animationDuration @animationEasing 0s; + } + .ui.animated.button .visible.content { + left: auto; + right: 0; + } + .ui.animated.button .hidden.content { + top: 50%; + left: auto; + right: -100%; + margin-top: -(@lineHeight / 2); + } + .ui.animated.button:focus .visible.content, + .ui.animated.button:hover .visible.content { + left: auto; + right: 200%; + } + .ui.animated.button:focus .hidden.content, + .ui.animated.button:hover .hidden.content { + left: auto; + right: 0; + } + + /* Vertical */ + .ui.vertical.animated.button .visible.content, + .ui.vertical.animated.button .hidden.content { + transition: top @animationDuration @animationEasing, transform @animationDuration @animationEasing; + } + .ui.vertical.animated.button .visible.content { + transform: translateY(0%); + right: auto; + } + .ui.vertical.animated.button .hidden.content { + top: -50%; + left: 0; + right: auto; + } + .ui.vertical.animated.button:focus .visible.content, + .ui.vertical.animated.button:hover .visible.content { + transform: translateY(200%); + right: auto; + } + .ui.vertical.animated.button:focus .hidden.content, + .ui.vertical.animated.button:hover .hidden.content { + top: 50%; + right: auto; + } + + /* Fade */ + .ui.fade.animated.button .visible.content, + .ui.fade.animated.button .hidden.content { + transition: opacity @animationDuration @animationEasing, transform @animationDuration @animationEasing; + } + .ui.fade.animated.button .visible.content { + left: auto; + right: auto; + opacity: 1; + transform: scale(1); + } + .ui.fade.animated.button .hidden.content { + opacity: 0; + left: 0; + right: auto; + transform: scale(@fadeScaleHigh); + } + .ui.fade.animated.button:focus .visible.content, + .ui.fade.animated.button:hover .visible.content { + left: auto; + right: auto; + opacity: 0; + transform: scale(@fadeScaleLow); + } + .ui.fade.animated.button:focus .hidden.content, + .ui.fade.animated.button:hover .hidden.content { + left: 0; + right: auto; + opacity: 1; + transform: scale(1); + } +} + +& when (@variationButtonInverted) { + /*------------------- + Inverted + --------------------*/ + + .ui.inverted.button { + box-shadow: 0 0 0 @invertedBorderSize @white inset; + background: transparent none; + color: @white; + text-shadow: none !important; + } + + /* Group */ + .ui.inverted.buttons .button { + margin: @invertedGroupButtonOffset; + } + .ui.inverted.buttons .button:first-child { + margin-left: 0; + } + .ui.inverted.vertical.buttons .button { + margin: @invertedVerticalGroupButtonOffset; + } + .ui.inverted.vertical.buttons .button:first-child { + margin-top: 0; + } + + /* States */ + + /* Hover */ + .ui.inverted.button:hover { + background: @white; + box-shadow: 0 0 0 @invertedBorderSize @white inset; + color: @hoverColor; + } + + /* Active / Focus */ + .ui.inverted.button:focus, + .ui.inverted.button.active { + background: @white; + box-shadow: 0 0 0 @invertedBorderSize @white inset; + color: @focusColor; + } + + /* Active Focus */ + .ui.inverted.button.active:focus { + background: @midWhite; + box-shadow: 0 0 0 @invertedBorderSize @midWhite inset; + color: @focusColor; + } +} + +& when (@variationButtonLabeled) or (@variationButtonLabeledIcon){ + /*------------------- + Labeled Button + --------------------*/ + + .ui.labeled.button:not(.icon) { + display: inline-flex; + flex-direction: row; + background: none; + padding: 0 !important; + border: none; + box-shadow: none; + } + + .ui.labeled.button > .button { + margin: 0; + } + .ui.labeled.button > .label { + display: flex; + align-items: @labeledLabelAlign; + margin: 0 0 0 @labeledLabelBorderOffset !important; + font-size: @labeledLabelFontSize; + padding: @labeledLabelPadding; + border-color: @labeledLabelBorderColor; + } + + /* Tag */ + .ui.labeled.button > .tag.label:before { + width: @labeledTagLabelSize; + height: @labeledTagLabelSize; + } + + /* Right */ + .ui.labeled.button:not([class*="left labeled"]) > .button { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + .ui.labeled.button:not([class*="left labeled"]) > .label { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + + /* Left Side */ + .ui[class*="left labeled"].button > .button { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + .ui[class*="left labeled"].button > .label { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } +} + +& when (@variationButtonSocial) { + /*------------------- + Social + --------------------*/ + + /* Facebook */ + .ui.facebook.button { + background-color: @facebookColor; + color: @invertedTextColor; + text-shadow: @invertedTextShadow; + background-image: @coloredBackgroundImage; + box-shadow: @coloredBoxShadow; + } + .ui.facebook.button:hover { + background-color: @facebookHoverColor; + color: @invertedTextColor; + text-shadow: @invertedTextShadow; + } + .ui.facebook.button:active { + background-color: @facebookDownColor; + color: @invertedTextColor; + text-shadow: @invertedTextShadow; + } + + /* Twitter */ + .ui.twitter.button { + background-color: @twitterColor; + color: @invertedTextColor; + text-shadow: @invertedTextShadow; + background-image: @coloredBackgroundImage; + box-shadow: @coloredBoxShadow; + } + .ui.twitter.button:hover { + background-color: @twitterHoverColor; + color: @invertedTextColor; + text-shadow: @invertedTextShadow; + } + .ui.twitter.button:active { + background-color: @twitterDownColor; + color: @invertedTextColor; + text-shadow: @invertedTextShadow; + } + + /* Google Plus */ + .ui.google.plus.button { + background-color: @googlePlusColor; + color: @invertedTextColor; + text-shadow: @invertedTextShadow; + background-image: @coloredBackgroundImage; + box-shadow: @coloredBoxShadow; + } + .ui.google.plus.button:hover { + background-color: @googlePlusHoverColor; + color: @invertedTextColor; + text-shadow: @invertedTextShadow; + } + .ui.google.plus.button:active { + background-color: @googlePlusDownColor; + color: @invertedTextColor; + text-shadow: @invertedTextShadow; + } + + /* Linked In */ + .ui.linkedin.button { + background-color: @linkedInColor; + color: @invertedTextColor; + text-shadow: @invertedTextShadow; + } + .ui.linkedin.button:hover { + background-color: @linkedInHoverColor; + color: @invertedTextColor; + text-shadow: @invertedTextShadow; + } + .ui.linkedin.button:active { + background-color: @linkedInDownColor; + color: @invertedTextColor; + text-shadow: @invertedTextShadow; + } + + /* YouTube */ + .ui.youtube.button { + background-color: @youtubeColor; + color: @invertedTextColor; + text-shadow: @invertedTextShadow; + background-image: @coloredBackgroundImage; + box-shadow: @coloredBoxShadow; + } + .ui.youtube.button:hover { + background-color: @youtubeHoverColor; + color: @invertedTextColor; + text-shadow: @invertedTextShadow; + } + .ui.youtube.button:active { + background-color: @youtubeDownColor; + color: @invertedTextColor; + text-shadow: @invertedTextShadow; + } + + /* Instagram */ + .ui.instagram.button { + background-color: @instagramColor; + color: @invertedTextColor; + text-shadow: @invertedTextShadow; + background-image: @coloredBackgroundImage; + box-shadow: @coloredBoxShadow; + } + .ui.instagram.button:hover { + background-color: @instagramHoverColor; + color: @invertedTextColor; + text-shadow: @invertedTextShadow; + } + .ui.instagram.button:active { + background-color: @instagramDownColor; + color: @invertedTextColor; + text-shadow: @invertedTextShadow; + } + + /* Pinterest */ + .ui.pinterest.button { + background-color: @pinterestColor; + color: @invertedTextColor; + text-shadow: @invertedTextShadow; + background-image: @coloredBackgroundImage; + box-shadow: @coloredBoxShadow; + } + .ui.pinterest.button:hover { + background-color: @pinterestHoverColor; + color: @invertedTextColor; + text-shadow: @invertedTextShadow; + } + .ui.pinterest.button:active { + background-color: @pinterestDownColor; + color: @invertedTextColor; + text-shadow: @invertedTextShadow; + } + + /* VK */ + .ui.vk.button { + background-color: @vkColor; + color: @white; + background-image: @coloredBackgroundImage; + box-shadow: @coloredBoxShadow; + } + .ui.vk.button:hover { + background-color: @vkHoverColor; + color: @white; + } + .ui.vk.button:active { + background-color: @vkDownColor; + color: @white; + } + + /* WhatsApp */ + .ui.whatsapp.button { + background-color: @whatsAppColor; + color: @white; + background-image: @coloredBackgroundImage; + box-shadow: @coloredBoxShadow; + } + .ui.whatsapp.button:hover { + background-color: @whatsAppHoverColor; + color: @white; + } + .ui.whatsapp.button:active { + background-color: @whatsAppDownColor; + color: @white; + } + + /* Telegram */ + .ui.telegram.button { + background-color: @telegramColor; + color: @white; + background-image: @coloredBackgroundImage; + box-shadow: @coloredBoxShadow; + } + .ui.telegram.button:hover { + background-color: @telegramHoverColor; + color: @white; + } + .ui.telegram.button:active { + background-color: @telegramDownColor; + color: @white; + } +} + +/*-------------- + Icon +---------------*/ + +.ui.button > .icon:not(.button) { + height: @iconHeight; + opacity: @iconOpacity; + transition: @iconTransition; + color: @iconColor; +} + +.ui.button:not(.icon) > .icon:not(.button):not(.dropdown), +.ui.button:not(.icon) > .icons:not(.button):not(.dropdown) { + margin: @iconMargin; + vertical-align: @iconVerticalAlign; +} +.ui.button:not(.icon) > .icons:not(.button):not(.dropdown) > .icon { + vertical-align: @iconVerticalAlign; +} +.ui.button:not(.icon) > .right.icon:not(.button):not(.dropdown) { + margin: @rightIconMargin; +} + +/******************************* + Variations +*******************************/ + +& when (@variationButtonFloated) { + /*------------------- + Floated + --------------------*/ + + .ui[class*="left floated"].buttons, + .ui[class*="left floated"].button { + float: left; + margin-left: 0; + margin-right: @floatedMargin; + } + + .ui[class*="right floated"].buttons, + .ui[class*="right floated"].button { + float: right; + margin-right: 0; + margin-left: @floatedMargin; + } +} + +& when (@variationButtonCompact) { + /*------------------- + Compact + --------------------*/ + + .ui.compact.buttons .button, + .ui.compact.button { + padding: @compactVerticalPadding @compactHorizontalPadding ( @compactVerticalPadding + @shadowOffset ); + } + + .ui.compact.icon.buttons .button, + .ui.compact.icon.button { + padding: @compactVerticalPadding @compactVerticalPadding ( @compactVerticalPadding + @shadowOffset ); + } + + .ui.compact.labeled.icon.buttons .button, + .ui.compact.labeled.icon.button { + padding: @compactVerticalPadding (@compactHorizontalPadding + @labeledIconWidth) ( @compactVerticalPadding + @shadowOffset ); + } + + .ui.compact.labeled.icon.buttons .button > .icon, + .ui.compact.labeled.icon.button > .icon { + padding: @compactVerticalPadding 0 @compactVerticalPadding 0; + } +} +/*------------------- + Sizes +--------------------*/ + +.ui.buttons .button, +.ui.buttons .or, +.ui.button { + font-size: @medium; +} + +& when not (@variationButtonSizes = false) { + each(@variationButtonSizes, { + @s: @@value; + .ui.@{value}.buttons .dropdown, + .ui.@{value}.buttons .dropdown .menu > .item, + .ui.@{value}.buttons .button, + .ui.@{value}.buttons .or, + .ui.ui.ui.ui.@{value}.button { + font-size: @s; + } + }) +} + +/*-------------- + Icon Only +---------------*/ + +.ui.icon.buttons .button, +.ui.icon.button:not(.animated):not(.compact) { + padding: @verticalPadding @verticalPadding ( @verticalPadding + @shadowOffset ); +} +.ui.animated.icon.button > .content > .icon, +.ui.icon.buttons .button > .icon, +.ui.icon.button > .icon { + opacity: @iconButtonOpacity; + margin: 0 !important; + vertical-align: top; +} +.ui.animated.button > .content > .icon { + vertical-align: top; +} + +& when (@variationButtonBasic) { + /*------------------- + Basic + --------------------*/ + + .ui.basic.buttons .button, + .ui.basic.button { + background: @basicBackground; + color: @basicTextColor; + font-weight: @basicFontWeight; + border-radius: @basicBorderRadius; + text-transform: @basicTextTransform; + text-shadow: none !important; + box-shadow: @basicBoxShadow; + } + + .ui.basic.buttons { + box-shadow: @basicGroupBoxShadow; + border: @basicGroupBorder; + border-radius: @borderRadius; + } + + .ui.basic.buttons .button { + border-radius: 0; + } + + .ui.basic.buttons .button:hover, + .ui.basic.button:hover { + background: @basicHoverBackground; + color: @basicHoverTextColor; + box-shadow: @basicHoverBoxShadow; + } + + .ui.basic.buttons .button:focus, + .ui.basic.button:focus { + background: @basicFocusBackground; + color: @basicFocusTextColor; + box-shadow: @basicFocusBoxShadow; + } + + .ui.basic.buttons .button:active, + .ui.basic.button:active { + background: @basicDownBackground; + color: @basicDownTextColor; + box-shadow: @basicDownBoxShadow; + } + + .ui.basic.buttons .active.button, + .ui.basic.active.button { + background: @basicActiveBackground; + box-shadow: @basicActiveBoxShadow; + color: @basicActiveTextColor; + } + + .ui.basic.buttons .active.button:hover, + .ui.basic.active.button:hover { + background-color: @transparentBlack; + } + + /* Vertical */ + .ui.basic.buttons .button:hover { + box-shadow: @basicHoverBoxShadow inset; + } + + .ui.basic.buttons .button:active { + box-shadow: @basicDownBoxShadow inset; + } + + .ui.basic.buttons .active.button { + box-shadow: @basicActiveBoxShadow; + } + & when (@variationButtonInverted) { + /* Standard Basic Inverted */ + + .ui.basic.inverted.buttons .button, + .ui.basic.inverted.button { + background-color: transparent; + color: @offWhite; + box-shadow: @basicInvertedBoxShadow; + } + + .ui.basic.inverted.buttons .button:hover, + .ui.basic.inverted.button:hover { + color: @white; + box-shadow: @basicInvertedHoverBoxShadow; + } + + .ui.basic.inverted.buttons .button:focus, + .ui.basic.inverted.button:focus { + color: @white; + box-shadow: @basicInvertedFocusBoxShadow; + } + + .ui.basic.inverted.buttons .button:active, + .ui.basic.inverted.button:active { + background-color: @transparentWhite; + color: @white; + box-shadow: @basicInvertedDownBoxShadow; + } + + .ui.basic.inverted.buttons .active.button, + .ui.basic.inverted.active.button { + background-color: @transparentWhite; + color: @invertedTextColor; + text-shadow: @invertedTextShadow; + box-shadow: @basicInvertedActiveBoxShadow; + } + + .ui.basic.inverted.buttons .active.button:hover, + .ui.basic.inverted.active.button:hover { + background-color: @strongTransparentWhite; + box-shadow: @basicInvertedHoverBoxShadow; + } + } + + & when (@variationButtonBasic) { + /* Basic Group */ + .ui.basic.buttons .button { + border-left: @basicGroupBorder; + box-shadow: none; + } + + .ui.basic.vertical.buttons .button { + border-left: none; + border-left-width: 0; + border-top: @basicGroupBorder; + } + + .ui.basic.vertical.buttons .button:first-child { + border-top-width: 0; + } + } +} + +& when (@variationButtonTertiary) { + /*------------------- + Tertiary + --------------------*/ + + /* Overline Mixin */ + .ui.tertiary.button { + transition: color @defaultDuration @defaultEasing !important; + border-radius: 0; + margin: (@verticalPadding - @tertiaryLinePadding) + (@horizontalMargin) + (@verticalPadding + @shadowOffset + @verticalMargin - @tertiaryLinePadding) + 0 !important; + padding: @tertiaryLinePadding !important; + + & when (@tertiaryWithUnderline = true) { + box-shadow: inset 0 -@tertiaryLineHeight 0 @tertiaryLineColor; + } + + & when (@tertiaryWithOverline = true) { + box-shadow: inset 0 @tertiaryLineHeight 0 @tertiaryLineColor; + } + + & when (@tertiaryWithUnderline = false) and (@tertiaryWithOverline = false){ + box-shadow: none; + } + + color: @tertiaryTextColor; + background: @tertiaryBackgroundColor; + } + + .ui.tertiary.button:hover { + + & when (@tertiaryHoverWithUnderline = true) { + box-shadow: inset 0 -@tertiaryLineHeight 0 @tertiaryHoverLineColor; + } + + & when (@tertiaryHoverWithOverline = true) { + box-shadow: inset 0 @tertiaryLineHeight 0 @tertiaryHoverLineColor; + } + + & when (@tertiaryHoverWithUnderline = false) and (@tertiaryHoverWithOverline = false) { + box-shadow: none; + } + + color: @tertiaryHoverColor; + background: @tertiaryHoverBackgroundColor; + } + + .ui.tertiary.button:focus { + & when (@tertiaryFocusWithUnderline = true) { + box-shadow: inset 0 -@tertiaryLineHeight 0 @tertiaryFocusLineColor; + } + + & when (@tertiaryFocusWithOverline = true) { + box-shadow: inset 0 @tertiaryLineHeight 0 @tertiaryFocusLineColor; + } + + & when (@tertiaryFocusWithUnderline = false) and (@tertiaryFocusWithOverline = false){ + box-shadow: none; + } + + color: @tertiaryFocusColor; + background: @tertiaryFocusBackgroundColor; + } + + .ui.tertiary.button:active { + & when (@tertiaryActiveWithUnderline = true) { + box-shadow: inset 0 -@tertiaryLineHeight 0 @tertiaryActiveLineColor; + border-radius: @borderRadius @borderRadius 0 0; + } + + & when (@tertiaryActiveWithOverline = true) { + box-shadow: inset 0 @tertiaryLineHeight 0 @tertiaryActiveLineColor; + border-radius: 0 0 @borderRadius @borderRadius; + } + + & when (@tertiaryActiveWithUnderline = false) and (@tertiaryActiveWithOverline = false){ + box-shadow: none; + border-radius: 0; + } + + color: @tertiaryActiveColor; + background: @tertiaryActiveBackgroundColor; + } +} + +& when (@variationButtonLabeledIcon) { + /*-------------- + Labeled Icon + ---------------*/ + + .ui.labeled.icon.buttons .button, + .ui.labeled.icon.button { + position: relative; + padding-left: @labeledIconPadding !important; + padding-right: @horizontalPadding !important; + } + + /* Left Labeled */ + .ui.labeled.icon.buttons > .button > .icon, + .ui.labeled.icon.button > .icon { + position: absolute; + top: 0; + left: 0; + height: 100%; + line-height: 1; + border-radius: 0; + border-top-left-radius: inherit; + border-bottom-left-radius: inherit; + text-align: center; + animation: none; + padding: @verticalPadding 0 @verticalPadding 0; + + margin: @labeledIconMargin; + width: @labeledIconWidth; + background-color: @labeledIconBackgroundColor; + color: @labeledIconColor; + box-shadow: @labeledIconLeftShadow; + } + + /* Right Labeled */ + .ui[class*="right labeled"].icon.button { + padding-right: @labeledIconPadding !important; + padding-left: @horizontalPadding !important; + } + + .ui[class*="right labeled"].icon.button > .icon { + left: auto; + right: 0; + border-radius: 0; + border-top-right-radius: inherit; + border-bottom-right-radius: inherit; + box-shadow: @labeledIconRightShadow; + } + + + .ui.labeled.icon.buttons > .button > .icon:before, + .ui.labeled.icon.button > .icon:before, + .ui.labeled.icon.buttons > .button > .icon:after, + .ui.labeled.icon.button > .icon:after { + display: block; + position: relative; + width: 100%; + top: 0; + text-align: center; + } + + .ui.labeled.icon.buttons .button > .icon { + border-radius: 0; + } + + .ui.labeled.icon.buttons .button:first-child > .icon { + border-top-left-radius: @borderRadius; + border-bottom-left-radius: @borderRadius; + } + + .ui.labeled.icon.buttons .button:last-child > .icon { + border-top-right-radius: @borderRadius; + border-bottom-right-radius: @borderRadius; + } + + .ui.vertical.labeled.icon.buttons .button:first-child > .icon { + border-radius: 0; + border-top-left-radius: @borderRadius; + } + + .ui.vertical.labeled.icon.buttons .button:last-child > .icon { + border-radius: 0; + border-bottom-left-radius: @borderRadius; + } + + /* Loading Icon in Labeled Button */ + .ui.labeled.icon.button > .loading.icon:before { + animation: loader 2s linear infinite; + } +} + +& when (@variationButtonToggle) { + /*-------------- + Toggle + ---------------*/ + + /* Toggle (Modifies active state to give affordances) */ + .ui.toggle.buttons .active.button, + .ui.buttons .button.toggle.active, + .ui.button.toggle.active { + background-color: @toggleBackgroundColor; + box-shadow: none; + text-shadow: @toggleTextShadow; + color: @toggleColor; + } + + .ui.button.toggle.active:hover { + background-color: @toggleHoverBackgroundColor; + text-shadow: @toggleHoverTextShadow; + color: @toggleHoverColor; + } +} + +& when (@variationButtonCircular) { + /*-------------- + Circular + ---------------*/ + + .ui.circular.button { + border-radius: @circularBorderRadius; + } + + .ui.circular.button > .icon { + width: @circularIconWidth; + vertical-align: baseline; + } +} + +& when (@variationButtonOr) { + /*------------------- + Or Buttons + --------------------*/ + + .ui.buttons .or { + position: relative; + width: @orGap; + height: @orHeight; + z-index: @orZIndex; + } + + .ui.buttons .or:before { + position: absolute; + text-align: center; + border-radius: @circularRadius; + + content: @orText; + top: 50%; + left: 50%; + background-color: @orBackgroundColor; + text-shadow: @orTextShadow; + + margin-top: @orVerticalOffset; + margin-left: @orHorizontalOffset; + + width: @orCircleSize; + height: @orCircleSize; + + line-height: @orLineHeight; + color: @orTextColor; + + font-style: @orTextStyle; + font-weight: @orTextWeight; + + box-shadow: @orBoxShadow; + } + + .ui.buttons .or[data-text]:before { + content: attr(data-text); + } + + /* Fluid Or */ + .ui.fluid.buttons .or { + width: 0 !important; + } + + .ui.fluid.buttons .or:after { + display: none; + } + +} + +& when (@variationButtonAttached) { + /*------------------- + Attached + --------------------*/ + + + /* Singular */ + .ui.attached.button { + position: relative; + display: block; + margin: 0; + border-radius: 0; + box-shadow: @attachedBoxShadow; + } + + /* Top / Bottom */ + .ui.attached.top.button { + border-radius: @borderRadius @borderRadius 0 0; + } + + .ui.attached.bottom.button { + border-radius: 0 0 @borderRadius @borderRadius; + } + + /* Left / Right */ + .ui.left.attached.button { + display: inline-block; + border-left: none; + text-align: right; + + padding-right: @attachedHorizontalPadding; + border-radius: @borderRadius 0 0 @borderRadius; + } + + .ui.right.attached.button { + display: inline-block; + text-align: left; + padding-left: @attachedHorizontalPadding; + border-radius: 0 @borderRadius @borderRadius 0; + } + + /* Plural */ + .ui.attached.buttons { + position: relative; + display: flex; + border-radius: 0; + width: auto !important; + z-index: @attachedZIndex; + margin-left: @attachedOffset; + margin-right: @attachedOffset; + } + + .ui.attached.buttons .button { + margin: 0; + } + + .ui.attached.buttons .button:first-child { + border-radius: 0; + } + + .ui.attached.buttons .button:last-child { + border-radius: 0; + } + + /* Top / Bottom */ + .ui[class*="top attached"].buttons { + margin-bottom: @attachedOffset; + border-radius: @borderRadius @borderRadius 0 0; + } + + .ui[class*="top attached"].buttons .button:first-child { + border-radius: @borderRadius 0 0 0; + } + + .ui[class*="top attached"].buttons .button:last-child { + border-radius: 0 @borderRadius 0 0; + } + + .ui[class*="bottom attached"].buttons { + margin-top: @attachedOffset; + border-radius: 0 0 @borderRadius @borderRadius; + } + + .ui[class*="bottom attached"].buttons .button:first-child { + border-radius: 0 0 0 @borderRadius; + } + + .ui[class*="bottom attached"].buttons .button:last-child { + border-radius: 0 0 @borderRadius 0; + } + + /* Left / Right */ + .ui[class*="left attached"].buttons { + display: inline-flex; + margin-right: 0; + margin-left: @attachedOffset; + border-radius: 0 @borderRadius @borderRadius 0; + } + + .ui[class*="left attached"].buttons .button:first-child { + margin-left: @attachedOffset; + border-radius: 0 @borderRadius 0 0; + } + + .ui[class*="left attached"].buttons .button:last-child { + margin-left: @attachedOffset; + border-radius: 0 0 @borderRadius 0; + } + + .ui[class*="right attached"].buttons { + display: inline-flex; + margin-left: 0; + margin-right: @attachedOffset; + border-radius: @borderRadius 0 0 @borderRadius; + } + + .ui[class*="right attached"].buttons .button:first-child { + margin-left: @attachedOffset; + border-radius: @borderRadius 0 0 0; + } + + .ui[class*="right attached"].buttons .button:last-child { + margin-left: @attachedOffset; + border-radius: 0 0 0 @borderRadius; + } +} + +& when (@variationButtonFluid) { + /*------------------- + Fluid + --------------------*/ + + .ui.fluid.buttons, + .ui.fluid.button { + width: 100%; + } + + .ui.fluid.button { + display: block; + } + + .ui.two.buttons { + width: 100%; + } + + .ui.two.buttons > .button { + width: 50%; + } + + .ui.three.buttons { + width: 100%; + } + + .ui.three.buttons > .button { + width: 33.333%; + } + + .ui.four.buttons { + width: 100%; + } + + .ui.four.buttons > .button { + width: 25%; + } + + .ui.five.buttons { + width: 100%; + } + + .ui.five.buttons > .button { + width: 20%; + } + + .ui.six.buttons { + width: 100%; + } + + .ui.six.buttons > .button { + width: 16.666%; + } + + .ui.seven.buttons { + width: 100%; + } + + .ui.seven.buttons > .button { + width: 14.285%; + } + + .ui.eight.buttons { + width: 100%; + } + + .ui.eight.buttons > .button { + width: 12.500%; + } + + .ui.nine.buttons { + width: 100%; + } + + .ui.nine.buttons > .button { + width: 11.11%; + } + + .ui.ten.buttons { + width: 100%; + } + + .ui.ten.buttons > .button { + width: 10%; + } + + .ui.eleven.buttons { + width: 100%; + } + + .ui.eleven.buttons > .button { + width: 9.09%; + } + + .ui.twelve.buttons { + width: 100%; + } + + .ui.twelve.buttons > .button { + width: 8.3333%; + } + + /* Fluid Vertical Buttons */ + .ui.fluid.vertical.buttons, + .ui.fluid.vertical.buttons > .button { + display: flex; + width: auto; + justify-content: center; + } + + .ui.two.vertical.buttons > .button { + height: 50%; + } + + .ui.three.vertical.buttons > .button { + height: 33.333%; + } + + .ui.four.vertical.buttons > .button { + height: 25%; + } + + .ui.five.vertical.buttons > .button { + height: 20%; + } + + .ui.six.vertical.buttons > .button { + height: 16.666%; + } + + .ui.seven.vertical.buttons > .button { + height: 14.285%; + } + + .ui.eight.vertical.buttons > .button { + height: 12.500%; + } + + .ui.nine.vertical.buttons > .button { + height: 11.11%; + } + + .ui.ten.vertical.buttons > .button { + height: 10%; + } + + .ui.eleven.vertical.buttons > .button { + height: 9.09%; + } + + .ui.twelve.vertical.buttons > .button { + height: 8.3333%; + } +} + +/*------------------- + Colors +--------------------*/ + +each(@colors, { + @color: replace(@key, '@', ''); + @c: @colors[@@color][color]; + @h: @colors[@@color][hover]; + @f: @colors[@@color][focus]; + @d: @colors[@@color][down]; + @a: @colors[@@color][active]; + @t: @colors[@@color][text]; + @s: @colors[@@color][shadow]; + @l: @colors[@@color][light]; + @lh: @colors[@@color][lightHover]; + @lf: @colors[@@color][lightFocus]; + @ld: @colors[@@color][lightDown]; + @la: @colors[@@color][lightActive]; + @lt: @colors[@@color][lightText]; + @ls: @colors[@@color][lightShadow]; + @ty: @colors[@@color][tertiary]; + @tyh: @colors[@@color][tertiaryHover]; + @tyf: @colors[@@color][tertiaryFocus]; + @tya: @colors[@@color][tertiaryActive]; + @isDark: @colors[@@color][isDark]; + @isVeryDark: @colors[@@color][isVeryDark]; + + .ui.@{color}.buttons .button, + .ui.@{color}.button { + background-color: @c; + color: @t; + text-shadow: @s; + background-image: @coloredBackgroundImage; + } + .ui.@{color}.button { + box-shadow: @coloredBoxShadow; + } + .ui.@{color}.buttons .button:hover, + .ui.@{color}.button:hover { + background-color: @h; + color: @t; + text-shadow: @s; + } + .ui.@{color}.buttons .button:focus, + .ui.@{color}.button:focus { + background-color: @f; + color: @t; + text-shadow: @s; + } + .ui.@{color}.buttons .button:active, + .ui.@{color}.button:active { + background-color: @d; + color: @t; + text-shadow: @s; + } + .ui.@{color}.buttons .active.button, + .ui.@{color}.buttons .active.button:active, + .ui.@{color}.active.button, + .ui.@{color}.button .active.button:active { + background-color: @a; + color: @t; + text-shadow: @s; + } + + & when (@variationButtonBasic) { + /* Basic */ + .ui.basic.@{color}.buttons .button, + .ui.basic.@{color}.button { + background: transparent; + box-shadow: 0 0 0 @basicBorderSize @c inset ; + color: @c ; + } + .ui.basic.@{color}.buttons .button:hover, + .ui.basic.@{color}.button:hover { + background: transparent ; + box-shadow: 0 0 0 @basicColoredBorderSize @h inset ; + color: @h ; + } + .ui.basic.@{color}.buttons .button:focus, + .ui.basic.@{color}.button:focus { + background: transparent ; + box-shadow: 0 0 0 @basicColoredBorderSize @f inset ; + color: @h ; + } + .ui.basic.@{color}.buttons .active.button, + .ui.basic.@{color}.active.button { + background: transparent ; + box-shadow: 0 0 0 @basicColoredBorderSize @a inset ; + color: @d ; + } + .ui.basic.@{color}.buttons .button:active, + .ui.basic.@{color}.button:active { + box-shadow: 0 0 0 @basicColoredBorderSize @d inset ; + color: @d ; + } + + .ui.buttons:not(.vertical) > .basic.@{color}.button:not(:first-child) { + margin-left: -@basicColoredBorderSize; + } + } + & when (@variationButtonInverted) { + /* Inverted */ + .ui.inverted.@{color}.buttons .button, + .ui.inverted.@{color}.button { + background-color: transparent; + + & when (@isDark) { + box-shadow: 0 0 0 @invertedBorderSize @solidBorderColor inset ; + color: @invertedTextColor; + } + + & when not (@isDark) { + box-shadow: 0 0 0 @invertedBorderSize @l inset ; + color: @l; + } + } + .ui.inverted.@{color}.buttons .button:hover, + .ui.inverted.@{color}.button:hover, + .ui.inverted.@{color}.buttons .button:focus, + .ui.inverted.@{color}.button:focus, + .ui.inverted.@{color}.buttons .button.active, + .ui.inverted.@{color}.button.active, + .ui.inverted.@{color}.buttons .button:active, + .ui.inverted.@{color}.button:active { + box-shadow: none ; + color: @lt; + } + .ui.inverted.@{color}.buttons .button:hover, + .ui.inverted.@{color}.button:hover { + background-color: @lh; + } + .ui.inverted.@{color}.buttons .button:focus, + .ui.inverted.@{color}.button:focus { + background-color: @lf; + } + .ui.inverted.@{color}.buttons .active.button, + .ui.inverted.@{color}.active.button { + background-color: @la; + } + .ui.inverted.@{color}.buttons .button:active, + .ui.inverted.@{color}.button:active { + background-color: @ld; + } + + /* Inverted Basic */ + .ui.inverted.@{color}.basic.buttons .button, + .ui.inverted.@{color}.buttons .basic.button, + .ui.inverted.@{color}.basic.button { + background-color: transparent; + box-shadow: @basicInvertedBoxShadow ; + color: @white ; + } + .ui.inverted.@{color}.basic.buttons .button:hover, + .ui.inverted.@{color}.buttons .basic.button:hover, + .ui.inverted.@{color}.basic.button:hover { + box-shadow: 0 0 0 @invertedBorderSize @lh inset ; + + & when (@isDark) { + color: @white ; + } + + & when not (@isDark) { + color: @l ; + } + } + .ui.inverted.@{color}.basic.buttons .button:focus, + .ui.inverted.@{color}.basic.buttons .button:focus, + .ui.inverted.@{color}.basic.button:focus { + box-shadow: 0 0 0 @invertedBorderSize @lf inset ; + color: @l ; + } + .ui.inverted.@{color}.basic.buttons .active.button, + .ui.inverted.@{color}.buttons .basic.active.button, + .ui.inverted.@{color}.basic.active.button { + box-shadow: 0 0 0 @invertedBorderSize @la inset ; + + & when (@isDark) { + color: @white ; + } + + & when not (@isDark) { + color: @l ; + } + } + & when (@variationButtonBasic) { + .ui.inverted.@{color}.basic.buttons .button:active, + .ui.inverted.@{color}.buttons .basic.button:active, + .ui.inverted.@{color}.basic.button:active { + box-shadow: 0 0 0 @invertedBorderSize @ld inset; + + & when (@isDark) { + color: @white; + } + + & when not (@isDark) { + color: @l; + } + } + } + } + + & when (@variationButtonTertiary) { + /* Tertiary */ + + .ui.tertiary.@{color}.buttons .button, + .ui.tertiary.@{color}.buttons .tertiary.button, + .ui.tertiary.@{color}.button { + background: transparent; + + + + & when (@tertiaryWithUnderline = true) { + box-shadow: inset 0 -@tertiaryLineHeight 0 @ty; + } + + & when (@tertiaryWithOverline = true) { + box-shadow: inset 0 @tertiaryLineHeight 0 @ty; + } + + & when (@tertiaryWithUnderline = false) and (@tertiaryWithOverline = false){ + box-shadow: none; + } + + color: @c; + } + + .ui.tertiary.@{color}.buttons .button:hover, + .ui.tertiary.@{color}.buttons button:hover, + .ui.tertiary.@{color}.button:hover { + + + + & when (@tertiaryHoverWithUnderline = true) { + box-shadow: inset 0 -@tertiaryLineHeight 0 @tyh; + } + + & when (@tertiaryHoverWithOverline = true) { + box-shadow: inset 0 @tertiaryLineHeight 0 @tyh; + } + + & when (@tertiaryHoverWithUnderline = false) and (@tertiaryHoverWithOverline = false) { + box-shadow: none; + } + + + color: @tyh; + } + + .ui.tertiary.@{color}.buttons .button:focus, + .ui.tertiary.@{color}.buttons .tertiary.button:focus, + .ui.tertiary.@{color}.button:focus { + + + + + & when (@tertiaryFocusWithUnderline = true) { + box-shadow: inset 0 -@tertiaryLineHeight 0 @tyf; + } + + & when (@tertiaryFocusWithOverline = true) { + box-shadow: inset 0 @tertiaryLineHeight 0 @tyf; + } + + & when (@tertiaryFocusWithUnderline = false) and (@tertiaryFocusWithOverline = false) { + box-shadow: none; + } + + + color: @tyf; + } + + .ui.tertiary.@{color}.buttons .active.button, + .ui.tertiary.@{color}.buttons .tertiary.active.button, + .ui.tertiary.@{color}.active.button, + .ui.tertiary.@{color}.buttons .button:active, + .ui.tertiary.@{color}.buttons .tertiary.button:active, + .ui.tertiary.@{color}.button:active { + + + + & when (@tertiaryActiveWithUnderline = true) { + box-shadow: inset 0 -@tertiaryLineHeight 0 @tya; + } + + & when (@tertiaryActiveWithOverline = true) { + box-shadow: inset 0 @tertiaryLineHeight 0 @tya; + } + + & when (@tertiaryActiveWithUnderline = false) and (@tertiaryActiveWithOverline = false) { + box-shadow: none; + } + + color: @a; + } + } +}) + +.addConsequence(@consequence) { + + @_backgroundColor: "@{consequence}Color"; + @_backgroundColorHover: "@{consequence}ColorHover"; + @_backgroundColorFocus: "@{consequence}ColorFocus"; + @_backgroundColorDown: "@{consequence}ColorDown"; + @_backgroundColorActive: "@{consequence}ColorActive"; + @_textColor: "@{consequence}TextColor"; + @_textShadow: "@{consequence}TextShadow"; + + /* Standard */ + .ui.@{consequence}.buttons .button, + .ui.@{consequence}.button { + background-color: @@_backgroundColor; + color: @@_textColor; + text-shadow: @@_textShadow; + background-image: @coloredBackgroundImage; + } + .ui.@{consequence}.button { + box-shadow: @coloredBoxShadow; + } + .ui.@{consequence}.buttons .button:hover, + .ui.@{consequence}.button:hover { + background-color: @@_backgroundColorHover; + color: @@_textColor; + text-shadow: @@_textShadow; + } + .ui.@{consequence}.buttons .button:focus, + .ui.@{consequence}.button:focus { + background-color: @@_backgroundColorFocus; + color: @@_textColor; + text-shadow: @@_textShadow; + } + .ui.@{consequence}.buttons .button:active, + .ui.@{consequence}.button:active { + background-color: @@_backgroundColorDown; + color: @@_textColor; + text-shadow: @@_textShadow; + } + .ui.@{consequence}.buttons .active.button, + .ui.@{consequence}.buttons .active.button:active, + .ui.@{consequence}.active.button, + .ui.@{consequence}.button .active.button:active { + background-color: @@_backgroundColorActive; + color: @@_textColor; + text-shadow: @@_textShadow; + } + & when (@variationButtonBasic) { + /* Basic */ + .ui.basic.@{consequence}.buttons .button, + .ui.basic.@{consequence}.button { + background: transparent; + box-shadow: 0 0 0 @basicBorderSize @@_backgroundColor inset; + color: @@_backgroundColor; + } + .ui.basic.@{consequence}.buttons .button:hover, + .ui.basic.@{consequence}.button:hover { + background: transparent; + box-shadow: 0 0 0 @basicColoredBorderSize @@_backgroundColorHover inset; + color: @@_backgroundColorHover; + } + .ui.basic.@{consequence}.buttons .button:focus, + .ui.basic.@{consequence}.button:focus { + background: transparent; + box-shadow: 0 0 0 @basicColoredBorderSize @@_backgroundColorFocus inset; + color: @@_backgroundColorHover; + } + .ui.basic.@{consequence}.buttons .active.button, + .ui.basic.@{consequence}.active.button { + background: transparent; + box-shadow: 0 0 0 @basicColoredBorderSize @@_backgroundColorActive inset; + color: @@_backgroundColorDown; + } + .ui.basic.@{consequence}.buttons .button:active, + .ui.basic.@{consequence}.button:active { + box-shadow: 0 0 0 @basicColoredBorderSize @@_backgroundColorDown inset; + color: @@_backgroundColorDown; + } + .ui.buttons:not(.vertical) > .basic.@{consequence}.button:not(:first-child) { + margin-left: -@basicColoredBorderSize; + } + } +} + +/*--------------- + Positive +----------------*/ + +.addConsequence(positive); + +/*--------------- + Negative +----------------*/ + +.addConsequence(negative); + +& when (@variationButtonGroups) { + /******************************* + Groups + *******************************/ + + .ui.buttons { + display: inline-flex; + flex-direction: row; + font-size: 0; + vertical-align: baseline; + margin: @verticalMargin @horizontalMargin 0 0; + } + + .ui.buttons:not(.basic):not(.inverted) { + box-shadow: @groupBoxShadow; + } + + /* Clearfix */ + .ui.buttons:after { + content: "."; + display: block; + height: 0; + clear: both; + visibility: hidden; + } + + /* Standard Group */ + .ui.buttons .button { + flex: 1 0 auto; + border-radius: 0; + margin: @groupButtonOffset; + } + + .ui.buttons:not(.basic):not(.inverted) > .button:not(.basic):not(.inverted) { + box-shadow: @groupButtonBoxShadow; + } + + .ui.buttons .button:first-child { + border-left: none; + margin-left: 0; + border-top-left-radius: @borderRadius; + border-bottom-left-radius: @borderRadius; + } + + .ui.buttons .button:last-child { + border-top-right-radius: @borderRadius; + border-bottom-right-radius: @borderRadius; + } + + /* Vertical Style */ + .ui.vertical.buttons { + display: inline-flex; + flex-direction: column; + } + + .ui.vertical.buttons .button { + display: block; + float: none; + width: 100%; + margin: @verticalGroupOffset; + box-shadow: @verticalBoxShadow; + border-radius: 0; + } + + .ui.vertical.buttons .button:first-child { + border-top-left-radius: @borderRadius; + border-top-right-radius: @borderRadius; + } + + .ui.vertical.buttons .button:last-child { + margin-bottom: 0; + border-bottom-left-radius: @borderRadius; + border-bottom-right-radius: @borderRadius; + } + + .ui.vertical.buttons .button:only-child { + border-radius: @borderRadius; + } +} +.loadUIOverrides(); diff --git a/semantic/src/definitions/elements/container.less b/semantic/src/definitions/elements/container.less new file mode 100644 index 0000000..26f1858 --- /dev/null +++ b/semantic/src/definitions/elements/container.less @@ -0,0 +1,160 @@ +/*! + * # Fomantic-UI - Container + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +/******************************* + Theme +*******************************/ + +@type : 'element'; +@element : 'container'; + +@import (multiple) '../../theme.config'; + +/******************************* + Container +*******************************/ + +/* All Sizes */ +.ui.container { + display: block; + max-width: @maxWidth; +} + +/* Mobile */ +@media only screen and (max-width: @largestMobileScreen) { + .ui.ui.ui.container:not(.fluid) { + width: @mobileWidth; + margin-left: @mobileGutter; + margin-right: @mobileGutter; + } + & when (@variationContainerGrid) or (@variationContainerRelaxed) { + .ui.ui.ui.grid.container { + width: @mobileGridWidth; + } + & when (@variationContainerRelaxed) { + .ui.ui.ui.relaxed.grid.container { + width: @mobileRelaxedGridWidth; + } + .ui.ui.ui.very.relaxed.grid.container { + width: @mobileVeryRelaxedGridWidth; + } + } + } +} + +/* Tablet */ +@media only screen and (min-width: @tabletBreakpoint) and (max-width: @largestTabletScreen) { + .ui.ui.ui.container:not(.fluid) { + width: @tabletWidth; + margin-left: @tabletGutter; + margin-right: @tabletGutter; + } + & when (@variationContainerGrid) or (@variationContainerRelaxed) { + .ui.ui.ui.grid.container { + width: @tabletGridWidth; + } + & when (@variationContainerRelaxed) { + .ui.ui.ui.relaxed.grid.container { + width: @tabletRelaxedGridWidth; + } + .ui.ui.ui.very.relaxed.grid.container { + width: @tabletVeryRelaxedGridWidth; + } + } + } +} + +/* Small Monitor */ +@media only screen and (min-width: @computerBreakpoint) and (max-width: @largestSmallMonitor) { + .ui.ui.ui.container:not(.fluid) { + width: @computerWidth; + margin-left: @computerGutter; + margin-right: @computerGutter; + } + & when (@variationContainerGrid) or (@variationContainerRelaxed) { + .ui.ui.ui.grid.container { + width: @computerGridWidth; + } + & when (@variationContainerRelaxed) { + .ui.ui.ui.relaxed.grid.container { + width: @computerRelaxedGridWidth; + } + .ui.ui.ui.very.relaxed.grid.container { + width: @computerVeryRelaxedGridWidth; + } + } + } +} + +/* Large Monitor */ +@media only screen and (min-width: @largeMonitorBreakpoint) { + .ui.ui.ui.container:not(.fluid) { + width: @largeMonitorWidth; + margin-left: @largeMonitorGutter; + margin-right: @largeMonitorGutter; + } + & when (@variationContainerGrid) or (@variationContainerRelaxed) { + .ui.ui.ui.grid.container { + width: @largeMonitorGridWidth; + } + & when (@variationContainerRelaxed) { + .ui.ui.ui.relaxed.grid.container { + width: @largeMonitorRelaxedGridWidth; + } + .ui.ui.ui.very.relaxed.grid.container { + width: @largeMonitorVeryRelaxedGridWidth; + } + } + } +} + +/******************************* + Types +*******************************/ + +& when (@variationContainerText) { + /* Text Container */ + .ui.text.container { + font-family: @textFontFamily; + max-width: @textWidth; + line-height: @textLineHeight; + font-size: @textSize; + } +} + +& when (@variationContainerFluid) { + /* Fluid */ + .ui.fluid.container { + width: 100%; + } +} + +/******************************* + Variations +*******************************/ +& when (@variationContainerAligned) { + .ui[class*="left aligned"].container { + text-align: left; + } + .ui[class*="center aligned"].container { + text-align: center; + } + .ui[class*="right aligned"].container { + text-align: right; + } +} +& when (@variationContainerJustified) { + .ui.justified.container { + text-align: justify; + hyphens: auto; + } +} + +.loadUIOverrides(); diff --git a/semantic/src/definitions/elements/divider.less b/semantic/src/definitions/elements/divider.less new file mode 100644 index 0000000..d23167d --- /dev/null +++ b/semantic/src/definitions/elements/divider.less @@ -0,0 +1,298 @@ +/*! + * # Fomantic-UI - Divider + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +/******************************* + Theme +*******************************/ + +@type : 'element'; +@element : 'divider'; + +@import (multiple) '../../theme.config'; + + +/******************************* + Divider +*******************************/ + +.ui.divider { + margin: @margin; + + line-height: 1; + height: 0; + + font-weight: @fontWeight; + text-transform: @textTransform; + letter-spacing: @letterSpacing; + color: @color; + + user-select: none; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} + +/*-------------- + Basic +---------------*/ + +.ui.divider:not(.vertical):not(.horizontal) { + border-top: @shadowWidth @borderStyle @shadowColor; + border-bottom: @highlightWidth @borderStyle @highlightColor; +} + +/*-------------- + Coupling +---------------*/ + +/* Allow divider between each column row */ +.ui.grid > .column + .divider, +.ui.grid > .row > .column + .divider { + left: auto; +} + +& when (@variationDividerHorizontal) { + /*-------------- + Horizontal + ---------------*/ + + .ui.horizontal.divider { + display: table; + white-space: nowrap; + + height: auto; + margin: @horizontalMargin; + line-height: 1; + text-align: center; + } + + .ui.horizontal.divider:before, + .ui.horizontal.divider:after { + content: ''; + display: table-cell; + position: relative; + top: 50%; + width: 50%; + background-repeat: no-repeat; + } + + .ui.horizontal.divider:before { + background-position: right @horizontalDividerMargin top 50%; + } + .ui.horizontal.divider:after { + background-position: left @horizontalDividerMargin top 50%; + } +} + +& when (@variationDividerVertical) { + /*-------------- + Vertical + ---------------*/ + + .ui.vertical.divider { + position: absolute; + z-index: 2; + top: 50%; + left: 50%; + + margin: 0; + padding: 0; + width: auto; + height: 50%; + + line-height: 0; + text-align: center; + transform: translateX(-50%); + } + + .ui.vertical.divider:before, + .ui.vertical.divider:after { + position: absolute; + left: 50%; + content: ''; + z-index: 3; + + border-left: @shadowWidth @borderStyle @shadowColor; + border-right: @highlightWidth @borderStyle @highlightColor; + + width: 0; + height: @verticalDividerHeight; + } + + .ui.vertical.divider:before { + top: -100%; + } + .ui.vertical.divider:after { + top: auto; + bottom: 0; + } + + /* Inside grid */ + @media only screen and (max-width : @largestMobileScreen) { + + .ui.stackable.grid .ui.vertical.divider, + .ui.grid .stackable.row .ui.vertical.divider { + display: table; + white-space: nowrap; + height: auto; + margin: @horizontalMargin; + overflow: hidden; + line-height: 1; + text-align: center; + position: static; + top: 0; + left: 0; + transform: none; + } + + .ui.stackable.grid .ui.vertical.divider:before, + .ui.grid .stackable.row .ui.vertical.divider:before, + .ui.stackable.grid .ui.vertical.divider:after, + .ui.grid .stackable.row .ui.vertical.divider:after { + left: 0; + border-left: none; + border-right: none; + content: ''; + display: table-cell; + position: relative; + top: 50%; + width: 50%; + background-repeat: no-repeat; + } + + .ui.stackable.grid .ui.vertical.divider:before, + .ui.grid .stackable.row .ui.vertical.divider:before { + background-position: right @horizontalDividerMargin top 50%; + } + .ui.stackable.grid .ui.vertical.divider:after, + .ui.grid .stackable.row .ui.vertical.divider:after { + background-position: left @horizontalDividerMargin top 50%; + } + } +} + +& when (@variationDividerIcon) { + /*-------------- + Icon + ---------------*/ + + .ui.divider > .icon { + margin: @dividerIconMargin; + font-size: @dividerIconSize; + height: 1em; + vertical-align: middle; + } +} + +& when (@variationDividerHorizontal) { + /*-------------- + Header + ---------------*/ + .ui.horizontal.divider[class*="left aligned"] { + &:before { + display: none; + } + &:after { + width: 100%; + } + } + .ui.horizontal.divider[class*="right aligned"] { + &:before { + width: 100%; + } + &:after { + display: none; + } + } +} + +/******************************* + Variations +*******************************/ + +& when (@variationDividerHidden) { + /*-------------- + Hidden + ---------------*/ + + .ui.hidden.divider { + border-color: transparent !important; + } + + .ui.hidden.divider:before, + .ui.hidden.divider:after { + display: none; + } +} + +/*-------------- + Inverted +---------------*/ +& when (@variationDividerInverted) { + .ui.divider.inverted, + .ui.vertical.inverted.divider, + .ui.horizontal.inverted.divider { + color: @invertedTextColor; + } + .ui.divider.inverted, + .ui.divider.inverted:after, + .ui.divider.inverted:before { + border-top-color: @invertedShadowColor !important; + border-left-color: @invertedShadowColor !important; + border-bottom-color: @invertedHighlightColor !important; + border-right-color: @invertedHighlightColor !important; + } +} + +/*-------------- + Fitted +---------------*/ +& when (@variationDividerFitted) { + .ui.fitted.divider { + margin: 0; + } +} + +& when (@variationDividerClearing) { + /*-------------- + Clearing + ---------------*/ + + .ui.clearing.divider { + clear: both; + } +} + +& when (@variationDividerSection) { + /*-------------- + Section + ---------------*/ + + .ui.section.divider { + margin-top: @sectionMargin; + margin-bottom: @sectionMargin; + } +} + +/*-------------- + Sizes +---------------*/ + +.ui.divider { + font-size: @medium; +} +& when not (@variationDividerSizes = false) { + each(@variationDividerSizes, { + @s: @@value; + .ui.@{value}.divider { + font-size: @s; + } + }) +} + +.loadUIOverrides(); diff --git a/semantic/src/definitions/elements/emoji.less b/semantic/src/definitions/elements/emoji.less new file mode 100644 index 0000000..6e80621 --- /dev/null +++ b/semantic/src/definitions/elements/emoji.less @@ -0,0 +1,72 @@ +/*! + * # Fomantic UI - Emoji + * https://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * https://github.com/fomantic/Fomantic-UI/blob/master/LICENSE.md + * + */ + + +/******************************* + Theme +*******************************/ + +@type : 'element'; +@element : 'emoji'; + +@import (multiple) '../../theme.config'; + + +/******************************* + Emoji +*******************************/ + + +em[data-emoji] { + opacity: @opacity; + + speak: none; + backface-visibility: hidden; +} + +em[data-emoji]:before { + content:'\00A0\00A0\00A0\00A0\00A0\00A0\00A0'; + display: inline-block; + line-height: @emojiLineHeight; + background-repeat: no-repeat; + background-position: center center; + & when not (@emojiFileType = 'svg') { + background-size: contain; + } +} + + +/******************************* + States +*******************************/ + +em[data-emoji].disabled { + opacity: @disabledOpacity; +} + + +/******************************* + Variations +*******************************/ + +em[data-emoji].loading:before { + animation: loader @loadingDuration linear infinite; +} + + +/*------------------- + Link +--------------------*/ + +em[data-emoji].link:not(.disabled) { + cursor: pointer; +} + +.loadUIOverrides(); diff --git a/semantic/src/definitions/elements/flag.less b/semantic/src/definitions/elements/flag.less new file mode 100644 index 0000000..b691d18 --- /dev/null +++ b/semantic/src/definitions/elements/flag.less @@ -0,0 +1,52 @@ +/*! + * # Fomantic-UI - Flag + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + + +/******************************* + Theme +*******************************/ + +@type : 'element'; +@element : 'flag'; + +@import (multiple) '../../theme.config'; + + +/******************************* + Flag +*******************************/ + +i.flag:not(.icon) { + display: inline-block; + + width: @width; + height: @height; + + line-height: @height; + vertical-align: @verticalAlign; + margin: 0 @margin 0 0; + + text-decoration: inherit; + + speak: none; + -webkit-font-smoothing: antialiased; + backface-visibility: hidden; +} + +/* Sprite */ +i.flag:not(.icon):before { + display: inline-block; + content: ''; + background: url(@spritePath) no-repeat -108px -1976px; + width: @width; + height: @height; +} + +.loadUIOverrides(); diff --git a/semantic/src/definitions/elements/header.less b/semantic/src/definitions/elements/header.less new file mode 100644 index 0000000..669f316 --- /dev/null +++ b/semantic/src/definitions/elements/header.less @@ -0,0 +1,487 @@ +/*! + * # Fomantic-UI - Header + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + + +/******************************* + Theme +*******************************/ + +@type : 'element'; +@element : 'header'; + +@import (multiple) '../../theme.config'; + + +/******************************* + Header +*******************************/ + +/* Standard */ +.ui.header { + border: none; + margin: @margin; + padding: @verticalPadding @horizontalPadding; + font-family: @fontFamily; + font-weight: @fontWeight; + line-height: @lineHeight; + text-transform: @textTransform; + color: @textColor; +} + +.ui.header:first-child { + margin-top: @firstMargin; +} +.ui.header:last-child { + margin-bottom: @lastMargin; +} + +& when (@variationHeaderSub) { + /*-------------- + Sub Header + ---------------*/ + + .ui.header .sub.header { + display: block; + font-weight: @normal; + padding: 0; + margin: @subHeaderMargin; + font-size: @subHeaderFontSize; + line-height: @subHeaderLineHeight; + color: @subHeaderColor; + } +} + +/*-------------- + Icon +---------------*/ + +.ui.header > i.icon { + display: table-cell; + opacity: @iconOpacity; + font-size: @iconSize; + padding-top: @iconOffset; + vertical-align: @iconAlignment; +} + +/* With Text Node */ +.ui.header > i.icon:only-child { + display: inline-block; + padding: 0; + margin-right: @iconMargin; +} + +/*------------------- + Image +--------------------*/ + +.ui.header > .image:not(.icon), +.ui.header > img { + display: inline-block; + margin-top: @imageOffset; + width: @imageWidth; + height: @imageHeight; + vertical-align: @imageAlignment; +} +.ui.header > .image:not(.icon):only-child, +.ui.header > img:only-child { + margin-right: @imageMargin; +} + +/*-------------- + Content +---------------*/ + +.ui.header .content { + display: inline-block; + vertical-align: @contentAlignment; +} + +/* After Image */ +.ui.header > img + .content, +.ui.header > .image + .content { + padding-left: @imageMargin; + vertical-align: @contentImageAlignment; +} + +/* After Icon */ +.ui.header > i.icon + .content { + padding-left: @iconMargin; + display: table-cell; + vertical-align: @contentIconAlignment; +} + + +/*-------------- + Loose Coupling +---------------*/ + +.ui.header .ui.label { + font-size: @labelSize; + margin-left: @labelDistance; + vertical-align: @labelVerticalAlign; +} + +/* Positioning */ +.ui.header + p { + margin-top: @nextParagraphDistance; +} + + + +/******************************* + Types +*******************************/ + + +/*-------------- + Page +---------------*/ +& when not (@variationHeaderTags = false) { + each(@variationHeaderTags, { + @sf: @{value}SubHeaderFontSize; + @s: @@value; + @{value}.ui.header { + font-size: @s; + } + & when (@variationHeaderSub) { + @{value}.ui.header .sub.header { + font-size: @@sf; + } + } + }) +} + +/*-------------- + Content Heading +---------------*/ + +& when not (@variationHeaderSizes = false) { + each(@variationHeaderSizes, { + @sf: @{value}SubHeaderFontSize; + @shf: @{value}SubHeadingSize; + @s: @{value}FontSize;; + .ui.@{value}.header { + font-size: @@s; + & when (@@s >= 2) { + min-height: 1em; + } + } + & when (@variationHeaderSub) { + .ui.@{value}.header .sub.header { + font-size: @@sf; + } + .ui.@{value}.sub.header { + font-size: @@shf; + } + } + }) +} + +& when (@variationHeaderSub) { + /*-------------- + Sub Heading + ---------------*/ + + .ui.sub.header { + padding: 0; + margin-bottom: @subHeadingDistance; + font-weight: @subHeadingFontWeight; + font-size: @subHeadingFontSize; + text-transform: @subHeadingTextTransform; + color: @subHeadingColor; + } +} + +& when (@variationHeaderIcon) { + /*------------------- + Icon + --------------------*/ + + .ui.icon.header { + display: inline-block; + text-align: center; + margin: @iconHeaderTopMargin 0 @iconHeaderBottomMargin; + } + .ui.icon.header:after { + content: ''; + display: block; + height: 0; + clear: both; + visibility: hidden; + } + + .ui.icon.header:first-child { + margin-top: @iconHeaderFirstMargin; + } + .ui.icon.header > i.icon { + float: none; + display: block; + width: auto; + height: auto; + line-height: 1; + padding: 0; + font-size: @iconHeaderSize; + margin: 0 auto @iconHeaderMargin; + opacity: @iconHeaderOpacity; + } + .ui.icon.header .corner.icon { + font-size: @cornerIconHeaderSize; + } + .ui.icon.header .content { + display: block; + padding: 0; + } + .ui.icon.header > i.circular.icon { + font-size: @circularHeaderIconSize; + } + .ui.icon.header > i.square.icon { + font-size: @squareHeaderIconSize; + } + & when (@variationHeaderBlock) { + .ui.block.icon.header > i.icon { + margin-bottom: 0; + } + } + .ui.icon.header.aligned { + margin-left: auto; + margin-right: auto; + display: block; + } +} + +/******************************* + States +*******************************/ +& when (@variationHeaderDisabled) { + .ui.disabled.header { + opacity: @disabledOpacity; + } +} + + +/******************************* + Variations +*******************************/ + +& when (@variationHeaderInverted) { + /*------------------- + Inverted + --------------------*/ + + .ui.inverted.header { + color: @invertedColor; + } + .ui.inverted.header .sub.header { + color: @invertedSubHeaderColor; + } + & when (@variationHeaderAttached) { + .ui.inverted.attached.header { + background: @invertedAttachedBackground; + box-shadow: none; + border-color: transparent; + } + } + & when (@variationHeaderBlock) { + .ui.inverted.block.header { + background: @invertedBlockBackground; + box-shadow: none; + border-bottom: none; + } + } +} + + +/*------------------- + Colors +--------------------*/ + +each(@colors, { + @color: replace(@key, '@', ''); + @c: @colors[@@color][color]; + @l: @colors[@@color][light]; + @h: @colors[@@color][hover]; + @lh: @colors[@@color][lightHover]; + + .ui.@{color}.header { + color: @c; + } + a.ui.@{color}.header:hover { + color: @h; + } + & when (@variationHeaderDividing) { + .ui.@{color}.dividing.header { + border-bottom: @dividedColoredBorderWidth solid @c; + } + } + & when (@variationHeaderInverted) { + .ui.inverted.@{color}.header.header.header { + color: @l; + } + a.ui.inverted.@{color}.header.header.header:hover { + color: @lh; + } + .ui.inverted.@{color}.dividing.header { + border-bottom: @dividedColoredBorderWidth solid @l; + } + } +}) + +& when (@variationHeaderAligned) { + /*------------------- + Aligned + --------------------*/ + + .ui.left.aligned.header { + text-align: left; + } + .ui.right.aligned.header { + text-align: right; + } + .ui.centered.header, + .ui.center.aligned.header { + text-align: center; + } +} + +& when (@variationHeaderJustified) { + .ui.justified.header { + text-align: justify; + } + .ui.justified.header:after { + display: inline-block; + content: ''; + width: 100%; + } +} + +& when (@variationHeaderFloated) { + /*------------------- + Floated + --------------------*/ + + .ui.floated.header, + .ui[class*="left floated"].header { + float: left; + margin-top: 0; + margin-right: @floatedMargin; + } + .ui[class*="right floated"].header { + float: right; + margin-top: 0; + margin-left: @floatedMargin; + } +} + +& when (@variationHeaderFitted) { + /*------------------- + Fitted + --------------------*/ + + .ui.fitted.header { + padding: 0; + } +} + +& when (@variationHeaderDividing) { + /*------------------- + Dividing + --------------------*/ + + .ui.dividing.header { + padding-bottom: @dividedBorderPadding; + border-bottom: @dividedBorder; + } + .ui.dividing.header .sub.header { + padding-bottom: @dividedSubHeaderPadding; + } + .ui.dividing.header i.icon { + margin-bottom: @dividedIconPadding; + } + & when (@variationHeaderInverted) { + .ui.inverted.dividing.header { + border-bottom-color: @invertedDividedBorderColor; + } + } +} + +& when (@variationHeaderBlock) { + /*------------------- + Block + --------------------*/ + + .ui.block.header { + background: @blockBackground; + padding: @blockVerticalPadding @blockHorizontalPadding; + box-shadow: @blockBoxShadow; + border: @blockBorder; + border-radius: @blockBorderRadius; + } + .ui.block.header:not(h1):not(h2):not(h3):not(h4):not(h5):not(h6) { + font-size: @mediumBlock; + } + & when not (@variationHeaderSizes = false) { + each(@variationHeaderSizes, { + @s: @{value}Block; + .ui.@{value}.block.header { + font-size: @@s; + } + }) + } +} + +& when (@variationHeaderAttached) { + /*------------------- + Attached + --------------------*/ + + .ui.attached.header { + background: @attachedBackground; + padding: @attachedVerticalPadding @attachedHorizontalPadding; + margin: 0 @attachedOffset 0 @attachedOffset; + box-shadow: @attachedBoxShadow; + border: @attachedBorder; + border-radius: 0; + } + .ui.attached.block.header { + background: @blockBackground; + } + .ui.attached:not(.top).header { + border-top: none; + } + .ui.top.attached.header { + border-radius: @attachedBorderRadius @attachedBorderRadius 0 0; + } + .ui.bottom.attached.header { + border-radius: 0 0 @attachedBorderRadius @attachedBorderRadius; + } + + /* Attached Sizes */ + .ui.attached.header:not(h1):not(h2):not(h3):not(h4):not(h5):not(h6) { + font-size: @mediumAttachedSize; + } + & when not (@variationHeaderSizes = false) { + each(@variationHeaderSizes, { + @s: @{value}AttachedSize; + .ui.@{value}.attached.header { + font-size: @@s; + } + }) + } +} + +/*------------------- + Sizing +--------------------*/ + +.ui.header:not(h1):not(h2):not(h3):not(h4):not(h5):not(h6) { + font-size: @mediumFontSize; +} + +.loadUIOverrides(); diff --git a/semantic/src/definitions/elements/icon.less b/semantic/src/definitions/elements/icon.less new file mode 100644 index 0000000..e97ae46 --- /dev/null +++ b/semantic/src/definitions/elements/icon.less @@ -0,0 +1,374 @@ +/*! + * # Fomantic-UI - Icon + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + + +/******************************* + Theme +*******************************/ + +@type : 'element'; +@element : 'icon'; + +@import (multiple) '../../theme.config'; + + +/******************************* + Icon +*******************************/ + +@font-face { + font-family: 'Icons'; + src: @fallbackSRC; + src: @src; + font-style: normal; + font-weight: @normal; + font-variant: normal; + text-decoration: inherit; + text-transform: none; +} + +i.icon { + display: inline-block; + opacity: @opacity; + + margin: 0 @distanceFromText 0 0; + + width: @width; + height: @height; + + font-family: 'Icons'; + font-style: normal; + font-weight: @normal; + text-decoration: inherit; + text-align: center; + + speak: none; + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + backface-visibility: hidden; +} + +i.icon:before { + background: none !important; +} + +/******************************* + Types +*******************************/ + +& when (@variationIconLoading) { + /*-------------- + Loading + ---------------*/ + + i.icon.loading { + height: 1em; + line-height: 1; + animation: loader @loadingDuration linear infinite; + } +} + +/******************************* + States +*******************************/ + +i.icon:hover, i.icons:hover, +i.icon:active, i.icons:active, +i.emphasized.icon:not(.disabled), i.emphasized.icons:not(.disabled) { + opacity: 1; +} + +& when (@variationIconDisabled) { + i.disabled.icon, i.disabled.icons { + opacity: @disabledOpacity; + cursor: default; + pointer-events: none; + } +} + +/******************************* + Variations +*******************************/ + +& when (@variationIconFitted) { + /*------------------- + Fitted + --------------------*/ + + i.fitted.icon { + width: auto; + margin: 0 !important; + } +} + +& when (@variationIconLink) { + /*------------------- + Link + --------------------*/ + + i.link.icon:not(.disabled), i.link.icons:not(.disabled) { + cursor: pointer; + opacity: @linkOpacity; + transition: opacity @defaultDuration @defaultEasing; + } + i.link.icon:hover, i.link.icons:hover { + opacity: 1; + } +} + +& when (@variationIconCircular) { + /*------------------- + Circular + --------------------*/ + + i.circular.icon { + border-radius: 500em !important; + line-height: 1 !important; + + padding: @circularPadding !important; + box-shadow: @circularShadow; + + width: @circularSize !important; + height: @circularSize !important; + } + & when (@variationIconInverted) { + i.circular.inverted.icon { + border: none; + box-shadow: none; + } + } +} + +& when (@variationIconFlipped) { + /*------------------- + Flipped + --------------------*/ + + i.flipped.icon, + i.horizontally.flipped.icon { + transform: scale(-1, 1); + } + i.vertically.flipped.icon { + transform: scale(1, -1); + } +} + +& when (@variationIconRotated) { + /*------------------- + Rotated + --------------------*/ + + i.rotated.icon, + i.right.rotated.icon, + i.clockwise.rotated.icon { + transform: rotate(90deg); + } + + i.left.rotated.icon, + i.counterclockwise.rotated.icon { + transform: rotate(-90deg); + } + + i.halfway.rotated.icon { + transform: rotate(180deg); + } +} + +& when (@variationIconFlipped) and (@variationIconRotated) { + /*-------------------------- + Flipped & Rotated + ---------------------------*/ + + i.rotated.flipped.icon, + i.right.rotated.flipped.icon, + i.clockwise.rotated.flipped.icon { + transform: scale(-1, 1) rotate(90deg); + } + + i.left.rotated.flipped.icon, + i.counterclockwise.rotated.flipped.icon { + transform: scale(-1, 1) rotate(-90deg); + } + + i.halfway.rotated.flipped.icon { + transform: scale(-1, 1) rotate(180deg); + } + + i.rotated.vertically.flipped.icon, + i.right.rotated.vertically.flipped.icon, + i.clockwise.rotated.vertically.flipped.icon { + transform: scale(1, -1) rotate(90deg); + } + + i.left.rotated.vertically.flipped.icon, + i.counterclockwise.rotated.vertically.flipped.icon { + transform: scale(1, -1) rotate(-90deg); + } + + i.halfway.rotated.vertically.flipped.icon { + transform: scale(1, -1) rotate(180deg); + } +} + +& when (@variationIconBordered) { + /*------------------- + Bordered + --------------------*/ + + i.bordered.icon { + line-height: 1; + vertical-align: baseline; + + width: @borderedSize; + height: @borderedSize; + padding: @borderedVerticalPadding @borderedHorizontalPadding !important; + box-shadow: @borderedShadow; + } + & when (@variationIconInverted) { + i.bordered.inverted.icon { + border: none; + box-shadow: none; + } + } +} + +& when (@variationIconInverted) { + /*------------------- + Inverted + --------------------*/ + + /* Inverted Shapes */ + i.inverted.bordered.icon, + i.inverted.circular.icon { + background-color: @black; + color: @white; + } + + i.inverted.icon { + color: @white; + } +} + +/*------------------- + Colors +--------------------*/ + +each(@colors, { + @color: replace(@key, '@', ''); + @c: @colors[@@color][color]; + @l: @colors[@@color][light]; + + i.@{color}.icon.icon.icon.icon { + color: @c; + } + & when (@variationIconInverted) { + i.inverted.@{color}.icon.icon.icon.icon { + color: @l; + } + i.inverted.bordered.@{color}.icon.icon.icon.icon, + i.inverted.circular.@{color}.icon.icon.icon.icon { + background-color: @c; + color: @white; + } + } +}) + + +/*------------------- + Sizes +--------------------*/ + +i.icon, +i.icons { + font-size: @medium; + line-height: @lineHeight; +} +& when not (@variationIconSizes = false) { + each(@variationIconSizes, { + @s: @@value; + i.@{value}.@{value}.@{value}.icon, + i.@{value}.@{value}.@{value}.icons { + font-size: @s; + vertical-align: middle; + } + }) +} + +& when (@variationIconGroups) or (@variationIconCorner) { + /******************************* + Groups + *******************************/ + + i.icons { + display: inline-block; + position: relative; + line-height: 1; + } + + i.icons .icon { + position: absolute; + top: 50%; + left: 50%; + transform: translateX(-50%) translateY(-50%); + margin: 0; + } + + i.icons .icon:first-child { + position: static; + width: auto; + height: auto; + vertical-align: top; + transform: none; + } + + & when (@variationIconCorner) { + /* Corner Icon */ + i.icons .corner.icon { + top: auto; + left: auto; + right: 0; + bottom: 0; + transform: none; + font-size: @cornerIconSize; + text-shadow: @cornerIconShadow; + } + i.icons .icon.corner[class*="top right"] { + top: 0; + left: auto; + right: 0; + bottom: auto; + } + i.icons .icon.corner[class*="top left"] { + top: 0; + left: 0; + right: auto; + bottom: auto; + } + i.icons .icon.corner[class*="bottom left"] { + top: auto; + left: 0; + right: auto; + bottom: 0; + } + i.icons .icon.corner[class*="bottom right"] { + top: auto; + left: auto; + right: 0; + bottom: 0; + } + & when (@variationIconInverted) { + i.icons .inverted.corner.icon { + text-shadow: @cornerIconInvertedShadow; + } + } + } +} + +.loadUIOverrides(); diff --git a/semantic/src/definitions/elements/image.less b/semantic/src/definitions/elements/image.less new file mode 100644 index 0000000..651b81e --- /dev/null +++ b/semantic/src/definitions/elements/image.less @@ -0,0 +1,321 @@ +/*! + * # Fomantic-UI - Image + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + + +/******************************* + Theme +*******************************/ + +@type : 'element'; +@element : 'image'; + +@import (multiple) '../../theme.config'; + + +/******************************* + Image +*******************************/ + +.ui.image { + position: relative; + display: inline-block; + vertical-align: middle; + max-width: 100%; + background-color: @placeholderColor; +} + +img.ui.image { + display: block; +} + +.ui.image svg, +.ui.image img { + display: block; + max-width: 100%; + height: auto; +} + + +/******************************* + States +*******************************/ + +.ui.hidden.images, +.ui.ui.hidden.image { + display: none; +} +.ui.hidden.transition.images, +.ui.hidden.transition.image { + display: block; + visibility: hidden; +} +.ui.images > .hidden.transition { + display: inline-block; + visibility: hidden; +} + +& when (@variationImageDisabled) { + .ui.disabled.images, + .ui.disabled.image { + cursor: default; + opacity: @disabledOpacity; + } +} + + +/******************************* + Variations +*******************************/ + +& when (@variationImageInline) { + /*-------------- + Inline + ---------------*/ + + .ui.inline.image, + .ui.inline.image svg, + .ui.inline.image img { + display: inline-block; + } +} + +& when (@variationImageAligned) { + /*------------------ + Vertical Aligned + -------------------*/ + + .ui.top.aligned.image, + .ui.top.aligned.image svg, + .ui.top.aligned.image img { + display: inline-block; + vertical-align: top; + } + .ui.middle.aligned.image, + .ui.middle.aligned.image svg, + .ui.middle.aligned.image img { + display: inline-block; + vertical-align: middle; + } + .ui.bottom.aligned.image, + .ui.bottom.aligned.image svg, + .ui.bottom.aligned.image img { + display: inline-block; + vertical-align: bottom; + } + .ui.top.aligned.images .image, + .ui.images .ui.top.aligned.image { + align-self: flex-start; + } + .ui.middle.aligned.images .image, + .ui.images .ui.middle.aligned.image { + align-self: center; + } + .ui.bottom.aligned.images .image, + .ui.images .ui.bottom.aligned.image { + align-self: flex-end; + } +} + +& when (@variationImageRounded) { + /*-------------- + Rounded + ---------------*/ + + .ui.rounded.images .image, + .ui.rounded.image, + .ui.rounded.images .image > *, + .ui.rounded.image > * { + border-radius: @roundedBorderRadius; + } +} + +& when (@variationImageBordered) { + /*-------------- + Bordered + ---------------*/ + + .ui.bordered.images .image, + .ui.bordered.images img, + .ui.bordered.images svg, + .ui.bordered.image img, + .ui.bordered.image svg, + img.ui.bordered.image { + border: @imageBorder; + } +} + +& when (@variationImageCircular) { + /*-------------- + Circular + ---------------*/ + + .ui.circular.images, + .ui.circular.image { + overflow: hidden; + } + + .ui.circular.images .image, + .ui.circular.image, + .ui.circular.images .image > *, + .ui.circular.image > * { + -webkit-border-radius: @circularRadius; + -moz-border-radius: @circularRadius; + border-radius: @circularRadius; + } +} + +& when (@variationImageFluid) { + /*-------------- + Fluid + ---------------*/ + + .ui.fluid.images, + .ui.fluid.image, + .ui.fluid.images img, + .ui.fluid.images svg, + .ui.fluid.image svg, + .ui.fluid.image img { + display: block; + width: 100%; + height: auto; + } +} + +& when (@variationImageAvatar) { + /*-------------- + Avatar + ---------------*/ + + .ui.avatar.images .image, + .ui.avatar.images img, + .ui.avatar.images svg, + .ui.avatar.image img, + .ui.avatar.image svg, + .ui.avatar.image { + margin-right: @avatarMargin; + + display: inline-block; + width: @avatarSize; + height: @avatarSize; + + -webkit-border-radius: @circularRadius; + -moz-border-radius: @circularRadius; + border-radius: @circularRadius; + } +} + +& when (@variationImageSpaced) { + /*------------------- + Spaced + --------------------*/ + + .ui.spaced.image { + display: inline-block !important; + margin-left: @spacedDistance; + margin-right: @spacedDistance; + } + + .ui[class*="left spaced"].image { + margin-left: @spacedDistance; + margin-right: 0; + } + + .ui[class*="right spaced"].image { + margin-left: 0; + margin-right: @spacedDistance; + } +} + +& when (@variationImageFloated) { + /*------------------- + Floated + --------------------*/ + + .ui.floated.image, + .ui.floated.images { + float: left; + margin-right: @floatedHorizontalMargin; + margin-bottom: @floatedVerticalMargin; + } + .ui.right.floated.images, + .ui.right.floated.image { + float: right; + margin-right: 0; + margin-bottom: @floatedVerticalMargin; + margin-left: @floatedHorizontalMargin; + } + + .ui.floated.images:last-child, + .ui.floated.image:last-child { + margin-bottom: 0; + } +} + +& when (@variationImageCentered) { + .ui.centered.image { + display: block; + margin-left: auto; + margin-right: auto; + } + .ui.centered.images { + display: flex; + flex-direction: row; + flex-wrap: wrap; + align-items: stretch; + justify-content: center; + } +} + +/*-------------- + Sizes +---------------*/ + +.ui.medium.images .image, +.ui.medium.images img, +.ui.medium.images svg, +.ui.medium.image { + width: @mediumWidth; + height: auto; + font-size: @medium; +} +& when not (@variationImageSizes = false) { + each(@variationImageSizes, { + @w: @{value}Width; + @s: @@value; + .ui.@{value}.images .image, + .ui.@{value}.images img, + .ui.@{value}.images svg, + .ui.@{value}.image { + width: @@w; + height: auto; + font-size: @s; + } + }) +} + +& when (@variationImageGroups) { + /******************************* + Groups + *******************************/ + + .ui.images { + font-size: 0; + margin: 0 -@imageHorizontalMargin 0; + } + + .ui.images .image, + .ui.images > img, + .ui.images > svg { + display: inline-block; + margin: 0 @imageHorizontalMargin @imageVerticalMargin; + } +} + +.loadUIOverrides(); diff --git a/semantic/src/definitions/elements/input.less b/semantic/src/definitions/elements/input.less new file mode 100644 index 0000000..7782ede --- /dev/null +++ b/semantic/src/definitions/elements/input.less @@ -0,0 +1,565 @@ +/*! + * # Fomantic-UI - Input + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +/******************************* + Theme +*******************************/ + +@type : 'element'; +@element : 'input'; + +@import (multiple) '../../theme.config'; + + +/******************************* + Standard +*******************************/ + + +/*-------------------- + Inputs +---------------------*/ + +.ui.input { + position: relative; + font-weight: @normal; + font-style: normal; + display: inline-flex; + color: @inputColor; +} +.ui.input > input { + margin: 0; + max-width: 100%; + flex: 1 0 auto; + outline: none; + -webkit-tap-highlight-color: rgba(255, 255, 255, 0); + text-align: @textAlign; + line-height: @lineHeight; + + font-family: @inputFont; + padding: @padding; + + background: @background; + border: @border; + color: @inputColor; + border-radius: @borderRadius; + transition: @transition; + + box-shadow: @boxShadow; +} + + +/*-------------------- + Placeholder +---------------------*/ + +/* browsers require these rules separate */ + +.ui.input > input::-webkit-input-placeholder { + color: @placeholderColor; +} +.ui.input > input::-moz-placeholder { + color: @placeholderColor; +} +.ui.input > input:-ms-input-placeholder { + color: @placeholderColor; +} + + +/******************************* + States +*******************************/ +& when (@variationInputDisabled) { + /*-------------------- + Disabled + ---------------------*/ + + .ui.disabled.input, + .ui.input:not(.disabled) input[disabled] { + opacity: @disabledOpacity; + } + + .ui.disabled.input > input, + .ui.input:not(.disabled) input[disabled] { + pointer-events: none; + } +} + +/*-------------------- + Active +---------------------*/ + +.ui.input > input:active, +.ui.input.down input { + border-color: @downBorderColor; + background: @downBackground; + color: @downColor; + box-shadow: @downBoxShadow; +} + +& when (@variationInputLoading) { + /*-------------------- + Loading + ---------------------*/ + + .ui.loading.loading.input > i.icon:before { + position: absolute; + content: ''; + top: 50%; + left: 50%; + + margin: @loaderMargin; + width: @loaderSize; + height: @loaderSize; + + border-radius: @circularRadius; + border: @loaderLineWidth solid @loaderFillColor; + } + .ui.loading.loading.input > i.icon:after { + position: absolute; + content: ''; + top: 50%; + left: 50%; + + margin: @loaderMargin; + width: @loaderSize; + height: @loaderSize; + + animation: loader @loaderSpeed infinite linear; + + border: @loaderLineWidth solid @loaderLineColor; + border-radius: @circularRadius; + + box-shadow: 0 0 0 1px transparent; + } +} + + +/*-------------------- + Focus +---------------------*/ + +.ui.input.focus > input, +.ui.input > input:focus { + border-color: @focusBorderColor; + background: @focusBackground; + color: @focusColor; + box-shadow: @focusBoxShadow; +} +.ui.input.focus > input::-webkit-input-placeholder, +.ui.input > input:focus::-webkit-input-placeholder { + color: @placeholderFocusColor; +} +.ui.input.focus > input::-moz-placeholder, +.ui.input > input:focus::-moz-placeholder { + color: @placeholderFocusColor; +} +.ui.input.focus > input:-ms-input-placeholder, +.ui.input > input:focus:-ms-input-placeholder { + color: @placeholderFocusColor; +} + + +& when (@variationInputStates) { + /*-------------------- + States + ---------------------*/ + each(@formStates, { + @state: replace(@key, '@', ''); + + .ui.input.@{state} > input { + background-color: @formStates[@@state][background]; + border-color: @formStates[@@state][borderColor]; + color: @formStates[@@state][color]; + box-shadow: @formStates[@@state][boxShadow]; + } + + /* Placeholder */ + .ui.input.@{state} > input::-webkit-input-placeholder { + color: @formStates[@@state][inputPlaceholderColor]; + } + .ui.input.@{state} > input::-moz-placeholder { + color: @formStates[@@state][inputPlaceholderColor]; + } + .ui.input.@{state} > input:-ms-input-placeholder { + color: @formStates[@@state][inputPlaceholderColor] !important; + } + + /* Focused Placeholder */ + .ui.input.@{state} > input:focus::-webkit-input-placeholder { + color: @formStates[@@state][inputPlaceholderFocusColor]; + } + .ui.input.@{state} > input:focus::-moz-placeholder { + color: @formStates[@@state][inputPlaceholderFocusColor]; + } + .ui.input.@{state} > input:focus:-ms-input-placeholder { + color: @formStates[@@state][inputPlaceholderFocusColor] !important; + } + }) +} +/******************************* + Variations +*******************************/ + +& when (@variationInputTransparent) { + /*-------------------- + Transparent + ---------------------*/ + + + .ui.transparent.input > textarea, + .ui.transparent.input > input { + border-color: transparent !important; + background-color: transparent !important; + padding: 0; + box-shadow: none !important; + border-radius: 0 !important; + } + .field .ui.transparent.input > textarea { + padding: @padding; + } + + /* Transparent Icon */ + :not(.field) > .ui.transparent.icon.input > i.icon { + width: @transparentIconWidth; + } + :not(.field) > .ui.ui.ui.transparent.icon.input > input { + padding-left: 0; + padding-right: @transparentIconMargin; + } + :not(.field) > .ui.ui.ui.transparent[class*="left icon"].input > input { + padding-left: @transparentIconMargin; + padding-right: 0; + } + & when (@variationInputInverted) { + /* Transparent Inverted */ + .ui.transparent.inverted.input { + color: @transparentInvertedColor; + } + .ui.ui.transparent.inverted.input > textarea, + .ui.ui.transparent.inverted.input > input { + color: inherit; + } + + .ui.transparent.inverted.input > input::-webkit-input-placeholder { + color: @transparentInvertedPlaceholderColor; + } + .ui.transparent.inverted.input > input::-moz-placeholder { + color: @transparentInvertedPlaceholderColor; + } + .ui.transparent.inverted.input > input:-ms-input-placeholder { + color: @transparentInvertedPlaceholderColor; + } + } +} + +& when (@variationInputIcon) { + /*-------------------- + Icon + ---------------------*/ + + .ui.icon.input > i.icon { + cursor: default; + position: absolute; + line-height: 1; + text-align: center; + top: 0; + right: 0; + margin: 0; + height: 100%; + + width: @iconWidth; + opacity: @iconOpacity; + border-radius: 0 @borderRadius @borderRadius 0; + transition: @iconTransition; + } + .ui.icon.input > i.icon:not(.link) { + pointer-events: none; + } + .ui.ui.ui.ui.icon.input > textarea, + .ui.ui.ui.ui.icon.input > input { + padding-right: @iconMargin; + } + + .ui.icon.input > i.icon:before, + .ui.icon.input > i.icon:after { + left: 0; + position: absolute; + text-align: center; + top: 50%; + width: 100%; + margin-top: @iconOffset; + } + .ui.icon.input > i.link.icon { + cursor: pointer; + } + .ui.icon.input > i.circular.icon { + top: @circularIconVerticalOffset; + right: @circularIconHorizontalOffset; + } + + /* Left Icon Input */ + .ui[class*="left icon"].input > i.icon { + right: auto; + left: @borderWidth; + border-radius: @borderRadius 0 0 @borderRadius; + } + .ui[class*="left icon"].input > i.circular.icon { + right: auto; + left: @circularIconHorizontalOffset; + } + .ui.ui.ui.ui[class*="left icon"].input > textarea, + .ui.ui.ui.ui[class*="left icon"].input > input { + padding-left: @iconMargin; + padding-right: @horizontalPadding; + } + + /* Focus */ + .ui.icon.input > textarea:focus ~ i.icon, + .ui.icon.input > input:focus ~ i.icon { + opacity: 1; + } +} + +& when (@variationInputLabeled) { + /*-------------------- + Labeled + ---------------------*/ + + /* Adjacent Label */ + .ui.labeled.input > .label { + flex: 0 0 auto; + margin: 0; + font-size: @relativeMedium; + } + .ui.labeled.input > .label:not(.corner) { + padding-top: @verticalPadding; + padding-bottom: @verticalPadding; + } + + /* Regular Label on Left */ + .ui.labeled.input:not([class*="corner labeled"]) .label:first-child { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + .ui.labeled.input:not([class*="corner labeled"]) .label:first-child + input { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + border-left-color: transparent; + } + .ui.labeled.input:not([class*="corner labeled"]) .label:first-child + input:focus { + border-left-color: @focusBorderColor; + } + + /* Regular Label on Right */ + .ui[class*="right labeled"].input > input { + border-top-right-radius: 0 !important; + border-bottom-right-radius: 0 !important; + border-right-color: transparent !important; + } + .ui[class*="right labeled"].input > input + .label { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + + .ui[class*="right labeled"].input > input:focus { + border-right-color: @focusBorderColor !important; + } +} + +& when (@variationInputCorner) { + /* Corner Label */ + .ui.labeled.input .corner.label { + top: @labelCornerTop; + right: @labelCornerRight; + font-size: @labelCornerSize; + border-radius: 0 @borderRadius 0 0; + } + + /* Spacing with corner label */ + .ui[class*="corner labeled"]:not([class*="left corner labeled"]).labeled.input > textarea, + .ui[class*="corner labeled"]:not([class*="left corner labeled"]).labeled.input > input { + padding-right: @labeledMargin !important; + } + .ui[class*="corner labeled"].icon.input:not([class*="left corner labeled"]) > textarea, + .ui[class*="corner labeled"].icon.input:not([class*="left corner labeled"]) > input { + padding-right: @labeledIconInputMargin !important; + } + .ui[class*="corner labeled"].icon.input:not([class*="left corner labeled"]) > i.icon { + margin-right: @labeledIconMargin; + } + + /* Left Labeled */ + .ui[class*="left corner labeled"].labeled.input > textarea, + .ui[class*="left corner labeled"].labeled.input > input { + padding-left: @labeledMargin !important; + } + & when (@variationInputIcon) { + .ui[class*="left corner labeled"].icon.input > textarea, + .ui[class*="left corner labeled"].icon.input > input { + padding-left: @labeledIconInputMargin !important; + } + .ui[class*="left corner labeled"].icon.input > i.icon { + margin-left: @labeledIconMargin; + } + } +} +& when (@variationInputIcon) { + .ui.icon.input > textarea ~ i.icon { + height: @textareaIconHeight; + } + :not(.field) > .ui.transparent.icon.input > textarea ~ i.icon { + height: @transparentTextareaIconHeight; + } +} +& when (@variationInputCorner) { + /* Corner Label Position */ + .ui.input > .ui.corner.label { + top: @borderWidth; + right: @borderWidth; + } + .ui.input > .ui.left.corner.label { + right: auto; + left: @borderWidth; + } +} + +& when (@variationInputLabeled) or (@variationInputAction) { + /* Labeled and action input states */ + each(@formStates, { + @state: replace(@key, '@', ''); + @borderColor: @formStates[@@state][borderColor]; + + .ui.form .field.@{state} > .ui.action.input > .ui.button, + .ui.form .field.@{state} > .ui.labeled.input:not([class*="corner labeled"]) > .ui.label, + .ui.action.input.@{state} > .ui.button, + .ui.labeled.input.@{state}:not([class*="corner labeled"]) > .ui.label { + border-top: @borderWidth solid @borderColor; + border-bottom: @borderWidth solid @borderColor; + } + .ui.form .field.@{state} > .ui[class*="left action"].input > .ui.button, + .ui.form .field.@{state} > .ui.labeled.input:not(.right):not([class*="corner labeled"]) > .ui.label, + .ui[class*="left action"].input.@{state} > .ui.button, + .ui.labeled.input.@{state}:not(.right):not([class*="corner labeled"]) > .ui.label { + border-left: @borderWidth solid @borderColor; + } + .ui.form .field.@{state} > .ui.action.input:not([class*="left action"]) > input + .ui.button, + .ui.form .field.@{state} > .ui.right.labeled.input:not([class*="corner labeled"]) > input + .ui.label, + .ui.action.input.@{state}:not([class*="left action"]) > input + .ui.button, + .ui.right.labeled.input.@{state}:not([class*="corner labeled"]) > input + .ui.label { + border-right: @borderWidth solid @borderColor; + } + .ui.form .field.@{state} > .ui.right.labeled.input:not([class*="corner labeled"]) > .ui.label:first-child, + .ui.right.labeled.input.@{state}:not([class*="corner labeled"]) > .ui.label:first-child { + border-left: @borderWidth solid @borderColor; + } + }) +} + +& when (@variationInputAction) { + /*-------------------- + Action + ---------------------*/ + + .ui.action.input > .button, + .ui.action.input > .buttons { + display: flex; + align-items: center; + flex: 0 0 auto; + } + .ui.action.input > .button, + .ui.action.input > .buttons > .button { + padding-top: @verticalPadding; + padding-bottom: @verticalPadding; + margin: 0; + } + + /* Input when ui Left*/ + .ui[class*="left action"].input > input { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + border-left-color: transparent; + } + + /* Input when ui Right*/ + .ui.action.input:not([class*="left action"]) > input { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + border-right-color: transparent; + } + + /* Button and Dropdown */ + .ui.action.input > .dropdown:first-child, + .ui.action.input > .button:first-child, + .ui.action.input > .buttons:first-child > .button { + border-radius: @borderRadius 0 0 @borderRadius; + } + .ui.action.input > .dropdown:not(:first-child), + .ui.action.input > .button:not(:first-child), + .ui.action.input > .buttons:not(:first-child) > .button { + border-radius: 0; + } + .ui.action.input > .dropdown:last-child, + .ui.action.input > .button:last-child, + .ui.action.input > .buttons:last-child > .button { + border-radius: 0 @borderRadius @borderRadius 0; + } + + /* Input Focus */ + .ui.action.input:not([class*="left action"]) > input:focus { + border-right-color: @focusBorderColor; + } + + .ui.ui[class*="left action"].input > input:focus { + border-left-color: @focusBorderColor; + } +} + +& when (@variationInputInverted) { + /*-------------------- + Inverted + ---------------------*/ + + /* Standard */ + .ui.inverted.input > input { + border: none; + } +} + +& when (@variationInputFluid) { + /*-------------------- + Fluid + ---------------------*/ + + .ui.fluid.input { + display: flex; + } + .ui.fluid.input > input { + width: 0 !important; + } +} + +/*-------------------- + Size +---------------------*/ + +.ui.input { + font-size: @relativeMedium; +} +& when not (@variationInputSizes = false) { + each(@variationInputSizes, { + @s: @{value}InputSize; + .ui.@{value}.input { + font-size: @@s; + } + }) +} + +.loadUIOverrides(); diff --git a/semantic/src/definitions/elements/label.less b/semantic/src/definitions/elements/label.less new file mode 100644 index 0000000..4517ed7 --- /dev/null +++ b/semantic/src/definitions/elements/label.less @@ -0,0 +1,1032 @@ +/*! + * # Fomantic-UI - Label + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + + +/******************************* + Theme +*******************************/ + +@type : 'element'; +@element : 'label'; + +@import (multiple) '../../theme.config'; + +/******************************* + Label +*******************************/ + +.ui.label { + display: inline-block; + line-height: 1; + vertical-align: @verticalAlign; + + margin: @verticalMargin @horizontalMargin; + + background-color: @backgroundColor; + background-image: @backgroundImage; + padding: @verticalPadding @horizontalPadding; + color: @color; + + text-transform: @textTransform; + font-weight: @fontWeight; + + border: @border; + border-radius: @borderRadius; + transition: @transition; +} + +.ui.label:first-child { + margin-left: 0; +} +.ui.label:last-child { + margin-right: 0; +} + +/* Link */ +a.ui.label { + cursor: pointer; +} + +/* Inside Link */ +.ui.label > a { + cursor: pointer; + color: inherit; + opacity: @linkOpacity; + transition: @linkTransition; +} +.ui.label > a:hover { + opacity: 1; +} + +/* Image */ +.ui.label > img { + width: auto !important; + vertical-align: middle; + height: @imageHeight; +} + +/* Icon */ +.ui.left.icon.label > .icon, +.ui.label > .icon { + width: auto; + margin: 0 @iconDistance 0 0; +} + +/* Detail */ +.ui.label > .detail { + display: inline-block; + vertical-align: top; + font-weight: @detailFontWeight; + margin-left: @detailMargin; + opacity: @detailOpacity; +} +.ui.label > .detail .icon { + margin: 0 @detailIconDistance 0 0; +} + +/* Removable label */ +.ui.label > .close.icon, +.ui.label > .delete.icon { + cursor: pointer; + font-size: @deleteSize; + opacity: @deleteOpacity; + transition: @deleteTransition; +} +.ui.label > .close.icon:hover, +.ui.label > .delete.icon:hover { + opacity: 1; +} + +/* Backward compatible positioning */ +.ui.label.left.icon > .close.icon, +.ui.label.left.icon > .delete.icon { + margin: 0 @deleteMargin 0 0; +} +.ui.label:not(.icon) > .close.icon, +.ui.label:not(.icon) > .delete.icon { + margin: 0 0 0 @deleteMargin; +} + +/* Label for only an icon */ +.ui.icon.label > .icon { + margin: 0 auto; +} + +/* Right Side Icon */ +.ui.right.icon.label > .icon { + margin: 0 0 0 @iconDistance; +} + +/*------------------- + Group +--------------------*/ + +.ui.labels > .label { + margin: 0 @groupHorizontalMargin @groupVerticalMargin 0; +} + + +/*------------------- + Coupling +--------------------*/ + +.ui.header > .ui.label { + margin-top: @lineHeightOffset; +} + + +/* Remove border radius on attached segment */ +.ui.attached.segment > .ui.top.left.attached.label, +.ui.bottom.attached.segment > .ui.top.left.attached.label { + border-top-left-radius: 0; +} +.ui.attached.segment > .ui.top.right.attached.label, +.ui.bottom.attached.segment > .ui.top.right.attached.label { + border-top-right-radius: 0; +} +.ui.top.attached.segment > .ui.bottom.left.attached.label { + border-bottom-left-radius: 0; +} +.ui.top.attached.segment > .ui.bottom.right.attached.label { + border-bottom-right-radius: 0; +} + +/* Padding on next content after a label */ +.ui.top.attached.label ~ .ui.bottom.attached.label + :not(.attached), +.ui.top.attached.label + :not(.attached) { + margin-top: @attachedSegmentPadding !important; +} +.ui.bottom.attached.label ~ :last-child:not(.attached) { + margin-top:0; + margin-bottom: @attachedSegmentPadding !important; +} + +.ui.segment:not(.basic) > .ui.top.attached.label { + margin-top: @attachedOffset; +} +.ui.segment:not(.basic) > .ui.bottom.attached.label { + margin-bottom: @attachedOffset; +} +.ui.segment:not(.basic) > .ui.attached.label:not(.right) { + margin-left: @attachedOffset; +} +.ui.segment:not(.basic) > .ui.right.attached.label { + margin-right: @attachedOffset; +} +.ui.segment:not(.basic) > .ui.attached.label:not(.left):not(.right) { + width: @attachedWidthOffset; +} + + + +/******************************* + Types +*******************************/ +& when (@variationLabelImage) { + .ui.image.label { + width: auto; + margin-top: 0; + margin-bottom: 0; + max-width: 9999px; + vertical-align: baseline; + text-transform: none; + + background: @imageLabelBackground; + padding: @imageLabelPadding; + border-radius: @imageLabelBorderRadius; + box-shadow: @imageLabelBoxShadow; + &.attached:not(.basic) when (@variationLabelAttached) { + padding: @imageLabelPadding; + } + } + + .ui.image.label img { + display: inline-block; + vertical-align: top; + + height: @imageLabelImageHeight; + margin: @imageLabelImageMargin; + border-radius: @imageLabelImageBorderRadius; + } + + .ui.image.label .detail { + background: @imageLabelDetailBackground; + margin: @imageLabelDetailMargin; + padding: @imageLabelDetailPadding; + border-radius: 0 @imageLabelBorderRadius @imageLabelBorderRadius 0; + } + & when (@variationLabelAttached) { + .ui.bottom.attached.image.label:not(.right) > img, + .ui.top.right.attached.image.label > img { + border-top-left-radius: 0; + } + + .ui.top.attached.image.label:not(.right) > img, + .ui.bottom.right.attached.image.label > img { + border-bottom-left-radius: 0; + } + } +} + +& when (@variationLabelTag) { +/*------------------- + Tag +--------------------*/ + + .ui.tag.labels .label, + .ui.tag.label { + margin-left: 1em; + position: relative; + padding-left: @tagHorizontalPadding; + padding-right: @tagHorizontalPadding; + + border-radius: 0 @borderRadius @borderRadius 0; + transition: @tagTransition; + } + .ui.tag.labels .label:before, + .ui.tag.label:before { + position: absolute; + transform: translateY(-50%) translateX(50%) rotate(-45deg); + + top: @tagTriangleTopOffset; + right: @tagTriangleRightOffset; + content: ''; + + background-color: inherit; + background-image: @tagTriangleBackgroundImage; + + width: @tagTriangleSize; + height: @tagTriangleSize; + transition: @tagTransition; + } + + + .ui.tag.labels .label:after, + .ui.tag.label:after { + position: absolute; + content: ''; + top: 50%; + left: -(@tagCircleSize / 2); + + margin-top: -(@tagCircleSize / 2); + background-color: @tagCircleColor; + width: @tagCircleSize; + height: @tagCircleSize; + + box-shadow: @tagCircleBoxShadow; + border-radius: @circularRadius; + } + & when (@variationLabelBasic) { + .ui.basic.tag.labels .label:before, + .ui.basic.tag.label:before { + border-color: inherit; + border-width: @basicBorderWidth 0 0 @basicBorderWidth; + border-style: inherit; + right: @basicBorderFullWidthOffset; + } + .ui.basic.tag.labels .label:after, + .ui.basic.tag.label:after { + box-shadow: @basicTagCircleBoxShadow; + } + } +} + +& when (@variationLabelCorner) { +/*------------------- + Corner Label +--------------------*/ + + .ui.corner.label { + position: absolute; + top: 0; + right: 0; + margin: 0; + padding: 0; + text-align: center; + + border-color: @backgroundColor; + + width: @cornerTriangleSize; + height: @cornerTriangleSize; + z-index: @cornerTriangleZIndex; + transition: @cornerTriangleTransition; + } + + /* Icon Label */ + .ui.corner.label{ + background-color: transparent !important; + } + .ui.corner.label:after { + position: absolute; + content: ""; + right: 0; + top: 0; + z-index: -1; + + width: 0; + height: 0; + background-color: transparent; + + border-top: 0 solid transparent; + border-right: @cornerTriangleSize solid transparent; + border-bottom: @cornerTriangleSize solid transparent; + border-left: 0 solid transparent; + + border-right-color: inherit; + transition: @cornerTriangleTransition; + } + + .ui.corner.label .icon { + cursor: inherit; + position: absolute; + top: @cornerIconTopOffset; + left: auto; + right: @cornerIconRightOffset; + font-size: @cornerIconSize; + margin: 0; + } + + /* Left Corner */ + .ui.left.corner.label, + .ui.left.corner.label:after { + right: auto; + left: 0; + } + .ui.left.corner.label:after { + border-top: @cornerTriangleSize solid transparent; + border-right: @cornerTriangleSize solid transparent; + border-bottom: 0 solid transparent; + border-left: 0 solid transparent; + + border-top-color: inherit; + } + .ui.left.corner.label .icon { + left: @cornerIconLeftOffset; + right: auto; + } + + /* Segment */ + .ui.segment > .ui.corner.label { + top: -1px; + right: -1px; + } + .ui.segment > .ui.left.corner.label { + right: auto; + left: -1px; + } +} + +& when (@variationLabelRibbon) { + /*------------------- + Ribbon + --------------------*/ + + .ui.ribbon.label { + position: relative; + margin: 0; + min-width: max-content; + border-radius: 0 @borderRadius @borderRadius 0; + border-color: @ribbonShadowColor; + } + + .ui.ribbon.label:after { + position: absolute; + content: ''; + + top: 100%; + left: 0; + background-color: transparent; + + border-style: solid; + border-width: 0 @ribbonTriangleSize @ribbonTriangleSize 0; + border-color: transparent; + border-right-color: inherit; + + width: 0; + height: 0; + } + /* Positioning */ + .ui.ribbon.label { + left: @ribbonOffset; + margin-right: -@ribbonTriangleSize; + padding-left: @ribbonDistance; + padding-right: @ribbonTriangleSize; + } + .ui[class*="right ribbon"].label { + left: @rightRibbonOffset; + padding-left: @ribbonTriangleSize; + padding-right: @ribbonDistance; + } + & when (@variationLabelBasic) { + .ui.basic.ribbon.label { + padding-top: @basicRibbonOffset; + padding-bottom: @basicRibbonOffset; + } + .ui.basic.ribbon.label:not([class*="right ribbon"]) { + padding-left: @basicRibbonTriangleSizeOffset; + padding-right: @basicRibbonTriangleSize; + } + .ui.basic[class*="right ribbon"].label { + padding-left: @basicRibbonTriangleSize; + padding-right: @basicRibbonTriangleSizeOffset; + } + .ui.basic.ribbon.label::after { + top: @basicBorderFullWidthOffset; + } + .ui.basic.ribbon.label:not([class*="right ribbon"])::after { + left: @basicBorderWidthOffset; + } + .ui.basic[class*="right ribbon"].label::after { + right: @basicBorderWidthOffset; + } + } + /* Right Ribbon */ + .ui[class*="right ribbon"].label { + text-align: left; + transform: translateX(-100%); + border-radius: @borderRadius 0 0 @borderRadius; + } + .ui[class*="right ribbon"].label:after { + left: auto; + right: 0; + + border-style: solid; + border-width: @ribbonTriangleSize @ribbonTriangleSize 0 0; + border-color: transparent; + border-top-color: inherit; + } + + /* Inside Table */ + .ui.image > .ribbon.label, + .ui.card .image > .ribbon.label { + position: absolute; + top: @ribbonImageTopDistance; + } + .ui.card .image > .ui.ribbon.label, + .ui.image > .ui.ribbon.label { + left: @ribbonImageOffset; + } + .ui.card .image > .ui[class*="right ribbon"].label, + .ui.image > .ui[class*="right ribbon"].label { + left: @rightRibbonImageOffset; + padding-left: @horizontalPadding; + } + + /* Inside Table */ + .ui.table td > .ui.ribbon.label { + left: @ribbonTableOffset; + } + .ui.table td > .ui[class*="right ribbon"].label { + left: @rightRibbonTableOffset; + padding-left: @horizontalPadding; + } +} + +& when (@variationLabelAttached) { + /*------------------- + Attached + --------------------*/ + + .ui[class*="top attached"].label, + .ui.attached.label { + width: 100%; + position: absolute; + margin: 0; + top: 0; + left: 0; + + padding: @attachedVerticalPadding @attachedHorizontalPadding; + + border-radius: @attachedCornerBorderRadius @attachedCornerBorderRadius 0 0; + } + .ui[class*="bottom attached"].label { + top: auto; + bottom: 0; + border-radius: 0 0 @attachedCornerBorderRadius @attachedCornerBorderRadius; + } + + .ui[class*="top left attached"].label { + width: auto; + margin-top: 0; + border-radius: @attachedCornerBorderRadius 0 @attachedBorderRadius 0; + } + + .ui[class*="top right attached"].label { + width: auto; + left: auto; + right: 0; + border-radius: 0 @attachedCornerBorderRadius 0 @attachedBorderRadius; + } + .ui[class*="bottom left attached"].label { + width: auto; + top: auto; + bottom: 0; + border-radius: 0 @attachedBorderRadius 0 @attachedCornerBorderRadius; + } + .ui[class*="bottom right attached"].label { + top: auto; + bottom: 0; + left: auto; + right: 0; + width: auto; + border-radius: @attachedBorderRadius 0 @attachedCornerBorderRadius 0; + } +} + +/******************************* + States +*******************************/ + +/*------------------- + Disabled +--------------------*/ +& when (@variationLabelDisabled) { + .ui.label.disabled { + opacity: 0.5; + } +} +/*------------------- + Hover +--------------------*/ + +.ui.labels a.label:hover, +a.ui.label:hover { + background-color: @labelHoverBackgroundColor; + border-color: @labelHoverBackgroundColor; + + background-image: @labelHoverBackgroundImage; + color: @labelHoverTextColor; +} +.ui.labels a.label:hover:before, +a.ui.label:hover:before { + color: @labelHoverTextColor; +} + +/*------------------- + Active +--------------------*/ + +.ui.active.label { + background-color: @labelActiveBackgroundColor; + border-color: @labelActiveBackgroundColor; + + background-image: @labelActiveBackgroundImage; + color: @labelActiveTextColor; +} +.ui.active.label:before { + background-color: @labelActiveBackgroundColor; + background-image: @labelActiveBackgroundImage; + color: @labelActiveTextColor; +} + +/*------------------- + Active Hover +--------------------*/ + +.ui.labels a.active.label:hover, +a.ui.active.label:hover { + background-color: @labelActiveHoverBackgroundColor; + border-color: @labelActiveHoverBackgroundColor; + + background-image: @labelActiveHoverBackgroundImage; + color: @labelActiveHoverTextColor; +} +.ui.labels a.active.label:hover:before, +a.ui.active.label:hover:before { + background-color: @labelActiveHoverBackgroundColor; + background-image: @labelActiveHoverBackgroundImage; + color: @labelActiveHoverTextColor; +} + + +/*------------------- + Visible +--------------------*/ + +.ui.labels.visible .label, +.ui.label.visible:not(.dropdown) { + display: inline-block !important; +} + +/*------------------- + Hidden +--------------------*/ + +.ui.labels.hidden .label, +.ui.label.hidden { + display: none !important; +} + + +/******************************* + Variations +*******************************/ + + +& when (@variationLabelBasic) { + /*------------------- + Basic + --------------------*/ + + .ui.basic.labels .label, + .ui.basic.label { + background: @basicBackground; + border: @basicBorder; + color: @basicColor; + box-shadow: @basicBoxShadow; + padding-top: @basicVerticalPadding; + padding-bottom: @basicVerticalPadding; + padding-right: @basicHorizontalPadding; + } + .ui.basic.labels:not(.tag):not(.image):not(.ribbon) .label, + .ui.basic.label:not(.tag):not(.image):not(.ribbon) { + padding-left: @basicHorizontalPadding; + } + & when (@variationLabelImage) { + .ui.basic.image.label { + padding-left: @basicImageLabelPadding; + } + } + + /* Link */ + .ui.basic.labels a.label:hover, + a.ui.basic.label:hover { + text-decoration: none; + background: @basicHoverBackground; + color: @basicHoverColor; + box-shadow: @basicHoverBoxShadow; + } + & when (@variationLabelPointing) { + /* Pointing */ + .ui.basic.pointing.label:before { + border-color: inherit; + } + } +} + +& when (@variationLabelFluid) { + /*------------------- + Fluid + --------------------*/ + + .ui.label.fluid, + .ui.fluid.labels > .label { + width: 100%; + box-sizing: border-box; + } +} + +& when (@variationLabelInverted) { + /*------------------- + Inverted + --------------------*/ + + .ui.inverted.labels .label, + .ui.inverted.label { + color: @invertedTextColor; + background-color: @invertedBackgroundColor; + } + .ui.inverted.corner.label { + border-color: @invertedBackgroundColor; + } + .ui.inverted.corner.label:hover { + border-color: @backgroundColor; + transition: none; + } + .ui.inverted.basic.labels .label, + .ui.inverted.basic.label, + .ui.inverted.basic.label:hover { + border-color: @basicInvertedBorderColor; + background: @black; + } + .ui.inverted.basic.label:hover { + color: @linkColor; + } +} + +/*------------------- + Colors +--------------------*/ + +each(@colors,{ + @color : replace(@key,'@',''); + @isDark : @colors[@@color][isDark]; + @_labelColor : @colors[@@color][color]; + @_labelInvertedColor : @colors[@@color][light]; + @_labelTextColor : @colors[@@color][text]; + @_labelHover : @colors[@@color][hover]; + @_labelInvertedHover : @colors[@@color][lightHover]; + @_labelHoverTextColor : @colors[@@color][hoverText]; + @_labelRibbonShadow : @colors[@@color][ribbon]; + @_labelInvertedRibbonShadow : @colors[@@color][invertedRibbon]; + + .ui.@{color}.labels .label, + .ui.ui.ui.@{color}.label { + background-color: @_labelColor; + border-color: @_labelColor; + color: @_labelTextColor; + } + /* Link */ + .ui.@{color}.labels a.label:hover, + a.ui.ui.ui.@{color}.label:hover{ + background-color: @_labelHover; + border-color: @_labelHover; + color: @_labelHoverTextColor; + } + & when (@variationLabelRibbon) { + /* Ribbon */ + .ui.ui.ui.@{color}.ribbon.label { + border-color: @_labelRibbonShadow; + } + } + & when (@variationLabelBasic) { + /* Basic */ + .ui.basic.labels .@{color}.label, + .ui.ui.ui.basic.@{color}.label { + background: @basicBackground; + border-color: @_labelColor; + color: @_labelColor; + } + .ui.basic.labels a.@{color}.label:hover, + a.ui.ui.ui.basic.@{color}.label:hover { + background: @basicBackground; + border-color: @_labelHover; + color: @_labelHover; + } + } + & when (@variationLabelInverted) { + /* Inverted */ + .ui.inverted.labels .@{color}.label, + .ui.ui.ui.inverted.@{color}.label { + background-color: @_labelInvertedColor; + border-color: @_labelInvertedColor; + color: @black; + } + /* Inverted Link */ + .ui.inverted.labels a.@{color}.label:hover, + a.ui.ui.ui.inverted.@{color}.label:hover{ + background-color: @_labelInvertedHover; + border-color: @_labelInvertedHover; + & when not (@isDark) { + color: @black; + } + & when (@isDark) { + color: @_labelTextColor; + } + } + & when (@variationLabelRibbon) { + /* Inverted Ribbon */ + .ui.ui.ui.inverted.@{color}.ribbon.label { + border-color: @_labelInvertedRibbonShadow; + } + } + & when (@variationLabelBasic) { + /* Inverted Basic */ + .ui.inverted.basic.labels .@{color}.label, + .ui.ui.ui.inverted.basic.@{color}.label { + background-color: @invertedBackground; + border-color: @_labelInvertedColor; + & when not (@isDark) { + color: @_labelInvertedColor; + } + & when (@isDark) { + color: @invertedTextColor; + } + } + .ui.inverted.basic.labels a.@{color}.label:hover, + a.ui.ui.ui.inverted.basic.@{color}.label:hover { + border-color: @_labelInvertedHover; + background-color: @invertedBackground; + & when not (@isDark) { + color: @_labelInvertedHover; + } + } + & when (@variationLabelTag) { + /* Inverted Basic Tags */ + .ui.inverted.basic.tag.labels .@{color}.label, + .ui.ui.ui.inverted.@{color}.basic.tag.label { + border: @invertedBorderSize solid @_labelInvertedColor; + } + .ui.inverted.basic.tag.labels .@{color}.label:before, + .ui.ui.ui.inverted.@{color}.basic.tag.label:before { + border-color: inherit; + border-width: @invertedBorderSize 0 0 @invertedBorderSize; + border-style: inherit; + background-color: @invertedBackground; + right: e(%("calc(100%% + %d)", @invertedBorderSize)); + } + } + } + } +}) + +/*------------------- + Horizontal +--------------------*/ + +.ui.horizontal.labels .label, +.ui.horizontal.label { + margin: 0 @horizontalLabelMargin 0 0; + + padding: @horizontalLabelVerticalPadding @horizontalPadding; + min-width: @horizontalLabelMinWidth; + text-align: center; +} + +& when (@variationLabelCircular) { + /*------------------- + Circular + --------------------*/ + + .ui.circular.labels .label, + .ui.circular.label { + min-width: @circularMinSize; + min-height: @circularMinSize; + + padding: @circularPadding !important; + + line-height: 1em; + text-align: center; + border-radius: @circularRadius; + } + .ui.empty.circular.labels .label, + .ui.empty.circular.label { + min-width: 0; + min-height: 0; + overflow: hidden; + width: @emptyCircleSize; + height: @emptyCircleSize; + vertical-align: baseline; + } +} + +& when (@variationLabelPointing) { + /*------------------- + Pointing + --------------------*/ + + .ui.pointing.label { + position: relative; + } + + .ui.attached.pointing.label { + position: absolute; + } + + .ui.pointing.label:before { + background-color: inherit; + background-image: inherit; + border-width: 0; + border-style: solid; + border-color: @pointingBorderColor; + } + /* Arrow */ + .ui.pointing.label:before { + position: absolute; + content: ''; + transform: rotate(45deg); + background-image: none; + + z-index: @pointingTriangleZIndex; + width: @pointingTriangleSize; + height: @pointingTriangleSize; + transition: @pointingTriangleTransition; + } + + /*--- Above ---*/ + .ui.pointing.label, + .ui[class*="pointing above"].label { + margin-top: @pointingVerticalDistance; + } + .ui.pointing.label:before, + .ui[class*="pointing above"].label:before { + border-width: @borderWidth 0 0 @borderWidth; + transform: translateX(-50%) translateY(-50%) rotate(45deg); + top: 0; + left: 50%; + } + /*--- Below ---*/ + .ui[class*="bottom pointing"].label, + .ui[class*="pointing below"].label { + margin-top: 0; + margin-bottom: @pointingVerticalDistance; + } + .ui[class*="bottom pointing"].label:before, + .ui[class*="pointing below"].label:before { + border-width: 0 @borderWidth @borderWidth 0; + top: auto; + right: auto; + transform: translateX(-50%) translateY(-50%) rotate(45deg); + top: 100%; + left: 50%; + } + /*--- Left ---*/ + .ui[class*="left pointing"].label { + margin-top: 0; + margin-left: @pointingHorizontalDistance; + } + .ui[class*="left pointing"].label:before { + border-width: 0 0 @borderWidth @borderWidth; + transform: translateX(-50%) translateY(-50%) rotate(45deg); + bottom: auto; + right: auto; + top: 50%; + left: 0; + } + /*--- Right ---*/ + .ui[class*="right pointing"].label { + margin-top: 0; + margin-right: @pointingHorizontalDistance; + } + .ui[class*="right pointing"].label:before { + border-width: @borderWidth @borderWidth 0 0; + transform: translateX(50%) translateY(-50%) rotate(45deg); + top: 50%; + right: 0; + bottom: auto; + left: auto; + } + & when (@variationLabelBasic) { + /* Basic Pointing */ + + /*--- Above ---*/ + .ui.basic.pointing.label:before, + .ui.basic[class*="pointing above"].label:before { + margin-top: @basicPointingTriangleOffset; + } + /*--- Below ---*/ + .ui.basic[class*="bottom pointing"].label:before, + .ui.basic[class*="pointing below"].label:before { + bottom: auto; + top: 100%; + margin-top: -@basicPointingTriangleOffset; + } + /*--- Left ---*/ + .ui.basic[class*="left pointing"].label:before { + top: 50%; + left: @basicPointingTriangleOffset; + } + /*--- Right ---*/ + .ui.basic[class*="right pointing"].label:before { + top: 50%; + right: @basicPointingTriangleOffset; + } + } +} + +& when (@variationLabelFloating) { + /*------------------ + Floating Label + -------------------*/ + + .ui.floating.label { + position: absolute; + z-index: @floatingZIndex; + top: @floatingTopOffset; + right: 0; + white-space: nowrap; + transform: translateX(50%); + } + .ui.right.aligned.floating.label { + transform: translateX(@floatingAlignOffset); + } + .ui.left.floating.label { + left:0; + right:auto; + transform: translateX(-50%); + } + .ui.left.aligned.floating.label { + transform: translateX(-@floatingAlignOffset); + } + .ui.bottom.floating.label { + top: auto; + bottom: @floatingBottomOffset; + } +} + +/*------------------- + Sizes +--------------------*/ + +.ui.labels .label, +.ui.label { + font-size: @medium; +} +& when not (@variationLabelSizes = false) { + each(@variationLabelSizes, { + @s: @@value; + .ui.@{value}.labels .label, + .ui.@{value}.label { + font-size: @s; + } + }) +} + +.loadUIOverrides(); diff --git a/semantic/src/definitions/elements/list.less b/semantic/src/definitions/elements/list.less new file mode 100644 index 0000000..ca1abdc --- /dev/null +++ b/semantic/src/definitions/elements/list.less @@ -0,0 +1,1021 @@ +/*! + * # Fomantic-UI - List + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +/******************************* + Theme +*******************************/ + +@type : 'element'; +@element : 'list'; + +@import (multiple) '../../theme.config'; + +/******************************* + List +*******************************/ + +ul.ui.list, +ol.ui.list, +.ui.list { + list-style-type: @listStyleType; + margin: @margin; + padding: @verticalPadding @horizontalPadding; +} + +ul.ui.list:first-child, +ol.ui.list:first-child, +.ui.list:first-child { + margin-top: 0; + padding-top: 0; +} + +ul.ui.list:last-child, +ol.ui.list:last-child, +.ui.list:last-child { + margin-bottom: 0; + padding-bottom: 0; +} + +/******************************* + Content +*******************************/ + +/* List Item */ +ul.ui.list li, +ol.ui.list li, +.ui.list > .item, +.ui.list .list > .item { + display: list-item; + table-layout: fixed; + list-style-type: @listStyleType; + list-style-position: @listStylePosition; + + padding: @itemPadding; + line-height: @itemLineHeight; +} + +ul.ui.list > li:first-child:after, +ol.ui.list > li:first-child:after, +.ui.list > .list > .item:after, +.ui.list > .item:after { + content: ''; + display: block; + height: 0; + clear: both; + visibility: hidden; +} + +ul.ui.list li:first-child, +ol.ui.list li:first-child, +.ui.list .list > .item:first-child, +.ui.list > .item:first-child { + padding-top: 0; +} +ul.ui.list li:last-child, +ol.ui.list li:last-child, +.ui.list .list > .item:last-child, +.ui.list > .item:last-child { + padding-bottom: 0; +} + +/* Child List */ +ul.ui.list ul, +ol.ui.list ol, +.ui.list .list:not(.icon) { + clear: both; + margin: 0; + padding: @childListPadding; +} + +/* Child Item */ +ul.ui.list ul li, +ol.ui.list ol li, +.ui.list .list > .item { + padding: @childItemPadding; + line-height: @childItemLineHeight; +} + +& when (@variationListIcon) { + /* Icon */ + .ui.list .list > .item > i.icon, + .ui.list > .item > i.icon { + display: table-cell; + min-width: 1.55em; + margin: 0; + padding-top: @iconOffset; + transition: @iconTransition; + &:not(.loading) { + padding-right: @iconDistance; + vertical-align: @iconContentVerticalAlign; + } + } + .ui.list .list > .item > i.icon:only-child, + .ui.list > .item > i.icon:only-child { + display: inline-block; + min-width: auto; + vertical-align: @iconVerticalAlign; + } +} + +& when (@variationListImage) { + /* Image */ + .ui.list .list > .item > .image, + .ui.list > .item > .image { + display: table-cell; + background-color: transparent; + margin: 0; + vertical-align: @imageAlign; + } + .ui.list .list > .item > .image:not(:only-child):not(img), + .ui.list > .item > .image:not(:only-child):not(img) { + padding-right: @imageDistance; + } + .ui.list .list > .item > .image img, + .ui.list > .item > .image img { + vertical-align: @imageAlign; + } + + .ui.list .list > .item > img.image, + .ui.list .list > .item > .image:only-child, + .ui.list > .item > img.image, + .ui.list > .item > .image:only-child { + display: inline-block; + } +} + +/* Content */ +.ui.list .list > .item > .content, +.ui.list > .item > .content { + line-height: @contentLineHeight; + color: @contentColor; +} +& when (@variationListImage) or (@variationListIcon) { + .ui.list .list > .item > .image + .content, + .ui.list .list > .item > i.icon + .content, + .ui.list > .item > .image + .content, + .ui.list > .item > i.icon + .content { + display: table-cell; + width: 100%; + padding: 0 0 0 @contentDistance; + vertical-align: @contentVerticalAlign; + } +} +& when (@variationListIcon) { + .ui.list .list > .item > i.loading.icon + .content, + .ui.list > .item > i.loading.icon + .content { + padding-left: e(%("calc(%d + %d)", @iconDistance, @contentDistance)); + } +} +& when (@variationListImage) { + .ui.list .list > .item > img.image + .content, + .ui.list > .item > img.image + .content { + display: inline-block; + width: auto; + } +} +.ui.list .list > .item > .content > .list, +.ui.list > .item > .content > .list { + margin-left: 0; + padding-left: 0; +} + +/* Header */ +.ui.list .list > .item .header, +.ui.list > .item .header { + display: block; + margin: 0; + font-family: @itemHeaderFontFamily; + font-weight: @itemHeaderFontWeight; + color: @itemHeaderColor; +} + +/* Description */ +.ui.list .list > .item .description, +.ui.list > .item .description { + display: block; + color: @itemDescriptionColor; +} + +/* Child Link */ +.ui.list > .item a, +.ui.list .list > .item a { + cursor: pointer; +} + +/* Linking Item */ +.ui.list .list > a.item, +.ui.list > a.item { + cursor: pointer; + color: @itemLinkColor; +} +.ui.list .list > a.item:hover, +.ui.list > a.item:hover { + color: @itemLinkHoverColor; +} + +& when (@variationListIcon) { + /* Linked Item Icons */ + .ui.list .list > a.item > i.icons, + .ui.list > a.item > i.icons, + .ui.list .list > a.item > i.icon, + .ui.list > a.item > i.icon { + color: @itemLinkIconColor; + } +} + +/* Header Link */ +.ui.list .list > .item a.header, +.ui.list > .item a.header { + cursor: pointer; + color: @itemHeaderLinkColor !important; +} +.ui.list .list > .item > a.header:hover, +.ui.list > .item > a.header:hover { + color: @itemHeaderLinkHoverColor !important; +} + +& when (@variationListFloated) { + /* Floated Content */ + .ui[class*="left floated"].list { + float: left; + } + .ui[class*="right floated"].list { + float: right; + } + + .ui.list .list > .item [class*="left floated"], + .ui.list > .item [class*="left floated"] { + float: left; + margin: @leftFloatMargin; + } + .ui.list .list > .item [class*="right floated"], + .ui.list > .item [class*="right floated"] { + float: right; + margin: @rightFloatMargin; + } +} + +/******************************* + Coupling +*******************************/ + +.ui.menu .ui.list > .item, +.ui.menu .ui.list .list > .item { + display: list-item; + table-layout: fixed; + background-color: transparent; + + list-style-type: @listStyleType; + list-style-position: @listStylePosition; + + padding: @itemVerticalPadding @itemHorizontalPadding; + line-height: @itemLineHeight; +} +.ui.menu .ui.list .list > .item:before, +.ui.menu .ui.list > .item:before { + border: none; + background: none; +} +.ui.menu .ui.list .list > .item:first-child, +.ui.menu .ui.list > .item:first-child { + padding-top: 0; +} +.ui.menu .ui.list .list > .item:last-child, +.ui.menu .ui.list > .item:last-child { + padding-bottom: 0; +} + + +/******************************* + Types +*******************************/ + +& when (@variationListHorizontal) { + /*------------------- + Horizontal + --------------------*/ + + .ui.horizontal.list { + display: inline-block; + font-size: 0; + } + .ui.horizontal.list > .item { + display: inline-block; + margin-right: @horizontalSpacing; + font-size: 1rem; + } + .ui.horizontal.list:not(.celled) > .item:last-child { + margin-right: 0; + padding-right: 0; + } + .ui.horizontal.list .list:not(.icon) { + padding-left: 0; + padding-bottom: 0; + } + .ui.horizontal.list > .item > .image, + .ui.horizontal.list .list > .item > .image, + .ui.horizontal.list > .item > i.icon, + .ui.horizontal.list .list > .item > i.icon, + .ui.horizontal.list > .item > .content, + .ui.horizontal.list .list > .item > .content { + vertical-align: @horizontalVerticalAlign; + } + + /* Padding on all elements */ + .ui.horizontal.list > .item:first-child, + .ui.horizontal.list > .item:last-child { + padding-top: @itemVerticalPadding; + padding-bottom: @itemVerticalPadding; + } + & when (@variationListIcon) { + /* Horizontal List */ + .ui.horizontal.list > .item > i.icon , + .ui.horizontal.list .item > i.icons > i.icon { + margin: 0; + padding: 0 @horizontalIconDistance 0 0; + } + } + & when (@variationListImage) or (@variationListIcon) { + .ui.horizontal.list > .item > .image + .content, + .ui.horizontal.list > .item > i.icon, + .ui.horizontal.list > .item > i.icon + .content { + float: none; + display: inline-block; + width: auto; + } + } + & when (@variationListImage) { + .ui.horizontal.list > .item > .image { + display: inline-block; + } + } +} + +/******************************* + States +*******************************/ + +& when (@variationListDisabled) { + /*------------------- + Disabled + --------------------*/ + + .ui.list .list > .disabled.item, + .ui.list > .disabled.item { + pointer-events: none; + color: @disabledColor !important; + } + & when (@variationListInverted) { + .ui.inverted.list .list > .disabled.item, + .ui.inverted.list > .disabled.item { + color: @invertedDisabledColor !important; + } + } +} + +/*------------------- + Hover +--------------------*/ +& when (@variationListIcon) { + .ui.list .list > a.item:hover > .icons, + .ui.list > a.item:hover > .icons, + .ui.list .list > a.item:hover > i.icon, + .ui.list > a.item:hover > i.icon { + color: @itemLinkIconHoverColor; + } +} + +/******************************* + Variations +*******************************/ + +& when (@variationListInverted) { + /*------------------- + Inverted + --------------------*/ + & when (@variationListIcon) { + .ui.inverted.list .list > a.item > i.icon, + .ui.inverted.list > a.item > i.icon { + color: @invertedIconLinkColor; + } + } + .ui.inverted.list .list > .item .header, + .ui.inverted.list > .item .header { + color: @invertedHeaderColor; + } + .ui.inverted.list .list > .item .description, + .ui.inverted.list > .item .description { + color: @invertedDescriptionColor; + } + .ui.inverted.list .list > .item > .content, + .ui.inverted.list > .item > .content { + color: @invertedContentColor; + } + /* Item Link */ + .ui.inverted.list .list > a.item, + .ui.inverted.list > a.item { + cursor: pointer; + color: @invertedItemLinkColor; + } + .ui.inverted.list .list > a.item:hover, + .ui.inverted.list > a.item:hover { + color: @invertedItemLinkHoverColor; + } + + + /* Linking Content */ + .ui.inverted.list .item a:not(.ui) { + color: @invertedItemLinkColor !important; + } + .ui.inverted.list .item a:not(.ui):hover { + color: @invertedItemLinkHoverColor !important; + } +} + +& when (@variationListAligned) { + /*------------------- + Aligned + --------------------*/ + + .ui.list[class*="top aligned"] .image, + .ui.list[class*="top aligned"] .content, + .ui.list [class*="top aligned"] { + vertical-align: top !important; + } + .ui.list[class*="middle aligned"] .image, + .ui.list[class*="middle aligned"] .content, + .ui.list [class*="middle aligned"] { + vertical-align: middle !important; + } + .ui.list[class*="bottom aligned"] .image, + .ui.list[class*="bottom aligned"] .content, + .ui.list [class*="bottom aligned"] { + vertical-align: bottom !important; + } +} + +& when (@variationListLink) { + /*------------------- + Link + --------------------*/ + + .ui.link.list .item, + .ui.link.list a.item, + .ui.link.list .item a:not(.ui) { + color: @linkListItemColor; + transition: @linkListTransition; + } + .ui.link.list.list a.item:hover, + .ui.link.list.list .item a:not(.ui):hover { + color: @linkListItemHoverColor; + } + .ui.link.list.list a.item:active, + .ui.link.list.list .item a:not(.ui):active { + color: @linkListItemDownColor; + } + .ui.link.list.list .active.item, + .ui.link.list.list .active.item a:not(.ui) { + color: @linkListItemActiveColor; + } + & when (@variationListInverted) { + /* Inverted */ + .ui.inverted.link.list .item, + .ui.inverted.link.list a.item, + .ui.inverted.link.list .item a:not(.ui) { + color: @invertedLinkListItemColor; + } + .ui.inverted.link.list.list a.item:hover, + .ui.inverted.link.list.list .item a:not(.ui):hover { + color: @invertedLinkListItemHoverColor; + } + .ui.inverted.link.list.list a.item:active, + .ui.inverted.link.list.list .item a:not(.ui):active { + color: @invertedLinkListItemDownColor; + } + .ui.inverted.link.list.list a.active.item, + .ui.inverted.link.list.list .active.item a:not(.ui) { + color: @invertedLinkListItemActiveColor; + } + } +} + +& when (@variationListSelection) { + /*------------------- + Selection + --------------------*/ + + .ui.selection.list .list > .item, + .ui.selection.list > .item { + cursor: pointer; + background: @selectionListBackground; + padding: @selectionListItemVerticalPadding @selectionListItemHorizontalPadding; + margin: @selectionListItemMargin; + color: @selectionListColor; + border-radius: @selectionListItemBorderRadius; + transition: @selectionListTransition; + } + .ui.selection.list .list > .item:last-child, + .ui.selection.list > .item:last-child { + margin-bottom: 0; + } + .ui.selection.list .list > .item:hover, + .ui.selection.list > .item:hover { + background: @selectionListHoverBackground; + color: @selectionListHoverColor; + } + .ui.selection.list .list > .item:active, + .ui.selection.list > .item:active { + background: @selectionListDownBackground; + color: @selectionListDownColor; + } + .ui.selection.list .list > .item.active, + .ui.selection.list > .item.active { + background: @selectionListActiveBackground; + color: @selectionListActiveColor; + } + + & when (@variationListInverted) { + /* Inverted */ + .ui.inverted.selection.list > .item { + background: @invertedSelectionListBackground; + color: @invertedSelectionListColor; + } + .ui.inverted.selection.list > .item:hover { + background: @invertedSelectionListHoverBackground; + color: @invertedSelectionListHoverColor; + } + .ui.inverted.selection.list > .item:active { + background: @invertedSelectionListDownBackground; + color: @invertedSelectionListDownColor; + } + .ui.inverted.selection.list > .item.active { + background: @invertedSelectionListActiveBackground; + color: @invertedSelectionListActiveColor; + } + } + + & when (@variationListCelled) or (@variationListDivided) { + /* Celled / Divided Selection List */ + .ui.celled.selection.list .list > .item, + .ui.divided.selection.list .list > .item, + .ui.celled.selection.list > .item, + .ui.divided.selection.list > .item { + border-radius: 0; + } + } +} + +& when (@variationListAnimated) { + /*------------------- + Animated + --------------------*/ + + .ui.animated.list > .item { + transition: @animatedListTransition; + } + .ui.animated.list:not(.horizontal) > .item:hover { + padding-left: @animatedListIndent; + } +} + +& when (@variationListFitted) { + /*------------------- + Fitted + --------------------*/ + .ui.fitted.list:not(.selection) .list > .item, + .ui.fitted.list:not(.selection) > .item { + padding-left: 0; + padding-right: 0; + } + .ui.fitted.selection.list .list > .item, + .ui.fitted.selection.list > .item { + margin-left: -@selectionListItemHorizontalPadding; + margin-right: -@selectionListItemHorizontalPadding; + } +} + +& when (@variationListBulleted) { + /*------------------- + Bulleted + --------------------*/ + + ul.ui.list, + .ui.bulleted.list { + margin-left: @bulletDistance; + } + ul.ui.list li, + .ui.bulleted.list .list > .item, + .ui.bulleted.list > .item { + position: relative; + } + ul.ui.list li:before, + .ui.bulleted.list .list > .item:before, + .ui.bulleted.list > .item:before { + user-select: none; + pointer-events: none; + position: absolute; + top: auto; + left: auto; + font-weight: @normal; + margin-left: @bulletOffset; + content: @bulletCharacter; + opacity: @bulletOpacity; + color: @bulletColor; + vertical-align: @bulletVerticalAlign; + } + + ul.ui.list li:before, + .ui.bulleted.list .list > a.item:before, + .ui.bulleted.list > a.item:before { + color: @bulletLinkColor; + } + + ul.ui.list ul, + .ui.bulleted.list .list:not(.icon) { + padding-left: @bulletChildDistance; + } + + & when (@variationListHorizontal) { + /* Horizontal Bulleted */ + ul.ui.horizontal.bulleted.list, + .ui.horizontal.bulleted.list { + margin-left: 0; + } + ul.ui.horizontal.bulleted.list li, + .ui.horizontal.bulleted.list > .item { + margin-left: @horizontalBulletSpacing; + } + ul.ui.horizontal.bulleted.list li:first-child, + .ui.horizontal.bulleted.list > .item:first-child { + margin-left: 0; + } + ul.ui.horizontal.bulleted.list li::before, + .ui.horizontal.bulleted.list > .item::before { + color: @horizontalBulletColor; + } + ul.ui.horizontal.bulleted.list li:first-child::before, + .ui.horizontal.bulleted.list > .item:first-child::before { + display: none; + } + } +} + +& when (@variationListOrdered) { + /*------------------- + Ordered + --------------------*/ + + ol.ui.list, + .ui.ordered.list, + .ui.ordered.list .list:not(.icon), + ol.ui.list ol { + counter-reset: ordered; + margin-left: @orderedCountDistance; + list-style-type: none; + } + ol.ui.list li, + .ui.ordered.list .list > .item, + .ui.ordered.list > .item { + list-style-type: none; + position: relative; + } + ol.ui.list li:before, + .ui.ordered.list .list > .item:before, + .ui.ordered.list > .item:before { + position: absolute; + top: auto; + left: auto; + user-select: none; + pointer-events: none; + margin-left: -(@orderedCountDistance); + counter-increment: @orderedCountName; + content: @orderedCountContent; + text-align: @orderedCountTextAlign; + color: @orderedCountColor; + vertical-align: @orderedCountVerticalAlign; + opacity: @orderedCountOpacity; + } + + & when (@variationListInverted) { + ol.ui.inverted.list li:before, + .ui.ordered.inverted.list .list > .item:before, + .ui.ordered.inverted.list > .item:before { + color: @orderedInvertedCountColor; + } + } + + /* Value */ + .ui.ordered.list .list > .item[data-value]:before, + .ui.ordered.list > .item[data-value]:before { + content: attr(data-value); + } + ol.ui.list li[value]:before { + content: attr(value); + } + + /* Child Lists */ + ol.ui.list ol, + .ui.ordered.list .list:not(.icon) { + margin-left: @orderedChildCountDistance; + } + ol.ui.list ol li:before, + .ui.ordered.list .list > .item:before { + margin-left: @orderedChildCountOffset; + } + + & when (@variationListHorizontal) { + /* Horizontal Ordered */ + ol.ui.horizontal.list, + .ui.ordered.horizontal.list { + margin-left: 0; + } + ol.ui.horizontal.list li:before, + .ui.ordered.horizontal.list .list > .item:before, + .ui.ordered.horizontal.list > .item:before { + position: static; + margin: 0 @horizontalOrderedCountDistance 0 0; + } + } +} + +& when (@variationListSuffixed) { + /* Suffixed Ordered */ + ol.ui.suffixed.list li:before, + .ui.suffixed.ordered.list .list > .item:before, + .ui.suffixed.ordered.list > .item:before { + content: @orderedCountContentSuffixed; + } +} + +& when (@variationListDivided) { + /*------------------- + Divided + --------------------*/ + + .ui.divided.list > .item { + border-top: @dividedBorder; + } + .ui.divided.list .list > .item { + border-top: @dividedChildListBorder; + } + .ui.divided.list .item .list > .item { + border-top: @dividedChildItemBorder; + } + .ui.divided.list .list > .item:first-child, + .ui.divided.list > .item:first-child { + border-top: none; + } + + /* Sub Menu */ + .ui.divided.list:not(.horizontal) .list > .item:first-child { + border-top-width: @dividedBorderWidth; + } + + & when (@variationListBulleted) { + /* Divided bulleted */ + .ui.divided.bulleted.list:not(.horizontal), + .ui.divided.bulleted.list .list:not(.icon) { + margin-left: 0; + padding-left: 0; + } + .ui.divided.bulleted.list > .item:not(.horizontal) { + padding-left: @bulletDistance; + } + } + + & when (@variationListOrdered) { + /* Divided Ordered */ + .ui.divided.ordered.list { + margin-left: 0; + } + .ui.divided.ordered.list .list > .item, + .ui.divided.ordered.list > .item { + padding-left: @orderedCountDistance; + } + .ui.divided.ordered.list .item .list:not(.icon) { + margin-left: 0; + margin-right: 0; + padding-bottom: @itemVerticalPadding; + } + .ui.divided.ordered.list .item .list > .item { + padding-left: @orderedChildCountDistance; + } + } + + & when (@variationListSelection) { + /* Divided Selection */ + + .ui.divided.selection.list .list > .item, + .ui.divided.selection.list > .item { + margin: 0; + border-radius: 0; + } + } + + & when (@variationListHorizontal) { + /* Divided horizontal */ + .ui.divided.horizontal.list { + margin-left: 0; + } + .ui.divided.horizontal.list > .item { + padding-left: @horizontalDividedSpacing; + } + .ui.divided.horizontal.list > .item:not(:last-child) { + padding-right: @horizontalDividedSpacing; + } + .ui.divided.horizontal.list > .item { + border-top: none; + border-right: @dividedBorder; + margin: 0; + line-height: @horizontalDividedLineHeight; + } + .ui.horizontal.divided.list > .item:last-child { + border-right: none; + } + } + + & when (@variationListInverted) { + /* Inverted */ + + .ui.divided.inverted.list > .item, + .ui.divided.inverted.list > .list, + .ui.divided.inverted.horizontal.list > .item { + border-color: @dividedInvertedBorderColor; + } + } +} + +& when (@variationListCelled) { + /*------------------- + Celled + --------------------*/ + + .ui.celled.list > .item, + .ui.celled.list > .list { + border-top: @celledBorder; + padding-left: @celledHorizontalPadding; + padding-right: @celledHorizontalPadding; + } + .ui.celled.list > .item:last-child { + border-bottom: @celledBorder; + } + + /* Padding on all elements */ + .ui.celled.list > .item:first-child, + .ui.celled.list > .item:last-child { + padding-top: @itemVerticalPadding; + padding-bottom: @itemVerticalPadding; + } + + /* Sub Menu */ + .ui.celled.list .item .list > .item { + border-width: 0; + } + .ui.celled.list .list > .item:first-child { + border-top-width: 0; + } + + & when (@variationListBulleted) { + /* Celled Bulleted */ + .ui.celled.bulleted.list { + margin-left: 0; + } + .ui.celled.bulleted.list .list > .item, + .ui.celled.bulleted.list > .item { + padding-left: (@bulletDistance); + } + .ui.celled.bulleted.list .item .list:not(.icon) { + margin-left: -(@bulletDistance); + margin-right: -(@bulletDistance); + padding-bottom: @itemVerticalPadding; + } + } + + & when (@variationListOrdered) { + /* Celled Ordered */ + .ui.celled.ordered.list { + margin-left: 0; + } + .ui.celled.ordered.list .list > .item, + .ui.celled.ordered.list > .item { + padding-left: @orderedCountDistance; + } + .ui.celled.ordered.list .item .list:not(.icon) { + margin-left: 0; + margin-right: 0; + padding-bottom: @itemVerticalPadding; + } + .ui.celled.ordered.list .list > .item { + padding-left: @orderedChildCountDistance; + } + } + + & when (@variationListHorizontal) { + /* Celled Horizontal */ + .ui.horizontal.celled.list { + margin-left: 0; + } + .ui.horizontal.celled.list .list > .item, + .ui.horizontal.celled.list > .item { + border-top: none; + border-left: @celledBorder; + margin: 0; + padding-left: @horizontalCelledSpacing; + padding-right: @horizontalCelledSpacing; + + line-height: @horizontalCelledLineHeight; + } + .ui.horizontal.celled.list .list > .item:last-child, + .ui.horizontal.celled.list > .item:last-child { + border-bottom: none; + border-right: @celledBorder; + } + } + + & when (@variationListInverted) { + /* Inverted */ + .ui.celled.inverted.list > .item, + .ui.celled.inverted.list > .list { + border-color: @celledInvertedBorder; + } + .ui.celled.inverted.horizontal.list .list > .item, + .ui.celled.inverted.horizontal.list > .item { + border-color: @celledInvertedBorder; + } + } +} + +& when (@variationListRelaxed) { + /*------------------- + Relaxed + --------------------*/ + + .ui.relaxed.list:not(.horizontal) > .item:not(:first-child) { + padding-top: @relaxedItemVerticalPadding; + } + .ui.relaxed.list:not(.horizontal) > .item:not(:last-child) { + padding-bottom: @relaxedItemVerticalPadding; + } + + & when (@variationListHorizontal) { + .ui.horizontal.relaxed.list .list > .item:not(:first-child), + .ui.horizontal.relaxed.list > .item:not(:first-child) { + padding-left: @relaxedHorizontalPadding; + } + .ui.horizontal.relaxed.list .list > .item:not(:last-child), + .ui.horizontal.relaxed.list > .item:not(:last-child) { + padding-right: @relaxedHorizontalPadding; + } + } + + /* Very Relaxed */ + .ui[class*="very relaxed"].list:not(.horizontal) > .item:not(:first-child) { + padding-top: @veryRelaxedItemVerticalPadding; + } + .ui[class*="very relaxed"].list:not(.horizontal) > .item:not(:last-child) { + padding-bottom: @veryRelaxedItemVerticalPadding; + } + + & when (@variationListHorizontal) { + .ui.horizontal[class*="very relaxed"].list .list > .item:not(:first-child), + .ui.horizontal[class*="very relaxed"].list > .item:not(:first-child) { + padding-left: @veryRelaxedHorizontalPadding; + } + .ui.horizontal[class*="very relaxed"].list .list > .item:not(:last-child), + .ui.horizontal[class*="very relaxed"].list > .item:not(:last-child) { + padding-right: @veryRelaxedHorizontalPadding; + } + } +} +/*------------------- + Sizes +--------------------*/ + +.ui.list { + font-size: @relativeMedium; +} +& when not (@variationListSizes = false) { + each(@variationListSizes, { + @rs: @{value}ListSize; + @s: @@value; + .ui.@{value}.list { + font-size: @@rs; + } + & when (@variationListHorizontal) { + .ui.@{value}.horizontal.list .list > .item, + .ui.@{value}.horizontal.list > .item { + font-size: @s; + } + } + }) +} + +.loadUIOverrides(); + diff --git a/semantic/src/definitions/elements/loader.less b/semantic/src/definitions/elements/loader.less new file mode 100644 index 0000000..0b64a84 --- /dev/null +++ b/semantic/src/definitions/elements/loader.less @@ -0,0 +1,416 @@ +/*! + * # Fomantic-UI - Loader + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ +/******************************* + Theme +*******************************/ + +@type : 'element'; +@element : 'loader'; + +@import (multiple) '../../theme.config'; + +/******************************* + Loader +*******************************/ + + +/* Standard Size */ +.ui.loader { + display: none; + position: absolute; + top: @loaderTopOffset; + left: @loaderLeftOffset; + margin: 0; + text-align: center; + z-index: 1000; + transform: translateX(-50%) translateY(-50%); +} + +/* Static Shape */ +.ui.loader:before { + position: absolute; + content: ''; + top: 0; + left: 50%; + width: 100%; + height: 100%; + + border-radius: @circularRadius; + border: @loaderLineWidth solid @loaderFillColor; +} + +/* Active Shape */ +.ui.loader:after { + position: absolute; + content: ''; + top: 0; + left: 50%; + width: 100%; + height: 100%; + + animation: loader @loaderSpeed infinite linear; + border: @loaderLineWidth solid @shapeBorderColor; + border-radius: @circularRadius; + + box-shadow: 0 0 0 1px transparent; +} + +& when (@variationLoaderSpeeds) { + /* Speeds */ + + .ui.fast.loading.loading:after, + .ui.fast.loading.loading .input > i.icon:after, + .ui.fast.loading.loading > i.icon:after, + .ui.fast.loader:after { + animation-duration: @loaderSpeedFast; + } + + .ui.slow.loading.loading:after, + .ui.slow.loading.loading .input > i.icon:after, + .ui.slow.loading.loading > i.icon:after, + .ui.slow.loader:after { + animation-duration: @loaderSpeedSlow; + } +} + +/* Active Animation */ +@keyframes loader { + 100% { + transform: rotate(360deg); + } +} + +/*------------------- + Coupling +--------------------*/ + +/* Show inside active dimmer */ +.ui.dimmer > .loader { + display: block; +} + +/* Black Dimmer */ +.ui.dimmer > .ui.loader { + color: @invertedLoaderTextColor; +} +.ui.dimmer > .ui.loader:not(.elastic):before { + border-color: @invertedLoaderFillColor; +} + +/* White Dimmer (Inverted) */ +.ui.inverted.dimmer > .ui.loader { + color: @loaderTextColor; +} +.ui.inverted.dimmer > .ui.loader:not(.elastic):before { + border-color: @loaderFillColor; +} + +/******************************* + Types +*******************************/ + +& when (@variationLoaderText) { + /*------------------- + Text + --------------------*/ + + .ui.ui.ui.ui.text.loader { + width: auto; + height: auto; + text-align: center; + font-style: normal; + } +} + + +/******************************* + States +*******************************/ +& when (@variationLoaderIndeterminate) { + .ui.indeterminate.loader:after { + animation-direction: @indeterminateDirection; + animation-duration: @indeterminateSpeed; + } +} + +.ui.loader.active, +.ui.loader.visible { + display: block; +} +.ui.loader.disabled, +.ui.loader.hidden { + display: none; +} + +/******************************* + Variations +*******************************/ + + +/*------------------- + Sizes +--------------------*/ + +.ui.loader { + width: @medium; + height: @medium; + font-size: @mediumFontSize; +} +.ui.loader:before, +.ui.loader:after { + width: @medium; + height: @medium; + margin: @mediumOffset; +} +& when (@variationLoaderText) { + .ui.text.loader { + min-width: @medium; + padding-top: (@medium + @textDistance); + } +} +& when not (@variationLoaderSizes = false) { + each(@variationLoaderSizes, { + @o: @{value}Offset; + @f: @{value}FontSize; + @s: @@value; + .ui.@{value}.loader { + width: @s; + height: @s; + font-size: @@f; + } + .ui.@{value}.loader:before, + .ui.@{value}.loader:after { + width: @s; + height: @s; + margin: @@o; + } + & when (@variationLoaderText) { + .ui.@{value}.text.loader { + min-width: @s; + padding-top: (@s + @textDistance); + } + } + }) +} + +/*------------------- + Colors +--------------------*/ + +each(@colors, { + @color: replace(@key, '@', ''); + @c: @colors[@@color][color]; + @l: @colors[@@color][light]; + + .ui.@{color}.elastic.loader.loader:before, + .ui.@{color}.basic.elastic.loading.button:before, + .ui.@{color}.basic.elastic.loading.button:after, + .ui.@{color}.elastic.loading.loading.loading:not(.segment):before, + .ui.@{color}.elastic.loading.loading.loading .input > i.icon:before, + .ui.@{color}.elastic.loading.loading.loading.loading > i.icon:before, + .ui.@{color}.loading.loading.loading.loading:not(.usual):not(.button):after, + .ui.@{color}.loading.loading.loading.loading .input > i.icon:after, + .ui.@{color}.loading.loading.loading.loading > i.icon:after, + .ui.@{color}.loader.loader.loader:after { + color: @c; + } + .ui.inverted.@{color}.elastic.loader:before, + .ui.inverted.@{color}.elastic.loading.loading.loading:not(.segment):before, + .ui.inverted.@{color}.elastic.loading.loading.loading .input > i.icon:before, + .ui.inverted.@{color}.elastic.loading.loading.loading > i.icon:before, + .ui.inverted.@{color}.loading.loading.loading.loading:not(.usual):after, + .ui.inverted.@{color}.loading.loading.loading.loading .input > i.icon:after, + .ui.inverted.@{color}.loading.loading.loading.loading > i.icon:after, + .ui.inverted.@{color}.loader.loader.loader:after { + color: @l; + } +}) + +.ui.elastic.loader.loader:before, +.ui.elastic.loading.loading.loading:before, +.ui.elastic.loading.loading.loading .input > i.icon:before, +.ui.elastic.loading.loading.loading > i.icon:before, +.ui.loading.loading.loading.loading:not(.usual):after, +.ui.loading.loading.loading.loading .input > i.icon:after, +.ui.loading.loading.loading.loading > i.icon:after, +.ui.loader.loader.loader:after { + border-color: currentColor; +} +.ui.elastic.loading.loading.loading.loading.button:not(.inverted):not(.basic):before { + color: @invertedLoaderLineColor; +} +.ui.elastic.basic.loading.button:before, +.ui.elastic.basic.loading.button:after { + color: @loaderLineColor; +} +.ui.double.loading.loading.loading.loading.button:after { + border-bottom-color: currentColor; +} + +& when (@variationLoaderInline) { + /*------------------- + Inline + --------------------*/ + + .ui.inline.loader { + position: relative; + vertical-align: @inlineVerticalAlign; + margin: @inlineMargin; + left: 0; + top: 0; + transform: none; + } + + .ui.inline.loader.active, + .ui.inline.loader.visible { + display: inline-block; + } + + /* Centered Inline */ + .ui.centered.inline.loader.active, + .ui.centered.inline.loader.visible { + display: block; + margin-left: auto; + margin-right: auto; + } +} + +.ui.loading.loading.loading.loading.loading.loading:after, +.ui.loading.loading.loading.loading.loading.loading .input > i.icon:after, +.ui.loading.loading.loading.loading.loading.loading > i.icon:after, +.ui.loader.loader.loader.loader.loader:after { + border-left-color:transparent; + border-right-color:transparent; +} +.ui.loading.loading.loading.loading.loading.loading.loading:not(.double):after, +.ui.loading.loading.loading.loading.loading.loading.loading:not(.double) .input > i.icon:after, +.ui.loading.loading.loading.loading.loading.loading.loading:not(.double) > i.icon:after, +.ui.loader.loader.loader.loader.loader.loader:not(.double):after { + border-bottom-color: transparent; +} +.ui.loading.loading.loading.loading.loading.loading.segment:after, +.ui.loading.loading.loading.loading.loading.loading.form:after { + border-left-color:@loaderFillColor; + border-right-color:@loaderFillColor; +} +.ui.loading.loading.loading.loading.loading.loading.segment:not(.double):after, +.ui.loading.loading.loading.loading.loading.loading.form:not(.double):after { + border-bottom-color: @loaderFillColor; +} + +& when (@variationLoaderElastic) { + /*------------------- + Elastic + --------------------*/ + + .ui.dimmer > .ui.elastic.loader { + color: @invertedLoaderLineColor; + } + .ui.inverted.dimmer > .ui.elastic.loader { + color: @loaderLineColor; + } + .ui.elastic.loading.loading:not(.form):not(.segment):after, + .ui.elastic.loading.loading .input > i.icon:after, + .ui.elastic.loading.loading > i.icon:after, + .ui.elastic.loader.loader:after { + animation: loader 1s infinite cubic-bezier(.27, 1.05, .92, .61); + animation-delay: 0.3s; + } + .ui.elastic.loading.loading.loading:not(.form):not(.segment):before, + .ui.elastic.loading.loading.loading .input > i.icon:before, + .ui.elastic.loading.loading.loading > i.icon:before, + .ui.elastic.loader.loader:before { + animation: elastic-loader 1s infinite cubic-bezier(.27, 1.05, .92, .61); + -moz-animation: currentcolor-elastic-loader 1s infinite cubic-bezier(.27, 1.05, .92, .61); + border-right-color: transparent; + } + & when (@variationLoaderInline) { + .ui.elastic.inline.loader:empty { + animation: loader 8s infinite linear; + } + } + & when (@variationLoaderSpeeds) { + .ui.slow.elastic.loading.loading:not(.form):not(.segment):after, + .ui.slow.elastic.loading.loading .input > i.icon:after, + .ui.slow.elastic.loading.loading > i.icon:after, + .ui.slow.elastic.loader.loader:after { + animation-duration: 1.5s; + animation-delay: 0.45s; + } + .ui.slow.elastic.loading.loading.loading:not(.form):not(.segment):before, + .ui.slow.elastic.loading.loading.loading .input > i.icon:before, + .ui.slow.elastic.loading.loading.loading > i.icon:before, + .ui.slow.elastic.loader.loader:before { + animation-duration: 1.5s; + } + .ui.fast.elastic.loading.loading:not(.form):not(.segment):after, + .ui.fast.elastic.loading.loading .input > i.icon:after, + .ui.fast.elastic.loading.loading > i.icon:after, + .ui.fast.elastic.loader.loader:after { + animation-duration: 0.66s; + animation-delay: 0.20s; + } + .ui.fast.elastic.loading.loading.loading:not(.form):not(.segment):before, + .ui.fast.elastic.loading.loading.loading .input > i.icon:before, + .ui.fast.elastic.loading.loading.loading > i.icon:before, + .ui.fast.elastic.loader.loader:before { + animation-duration: 0.66s; + } + } + @keyframes elastic-loader { + 0%, 1% { + border-left-color: transparent; + border-bottom-color: transparent + } + 1.1%, 50% { + border-left-color: inherit; + } + 10%, 35.1%{ + border-bottom-color: transparent; + } + 10.1%, 35%{ + border-bottom-color: inherit; + } + 50.1%{ + border-left-color: transparent; + } + 100% { + border-left-color: transparent; + border-bottom-color: transparent; + transform: rotate(360deg); + } + } + + @keyframes currentcolor-elastic-loader { + 0%, 1% { + border-left-color: transparent; + border-bottom-color: transparent + } + 1.1%, 50% { + border-left-color: currentColor; + } + 10%, 35.1%{ + border-bottom-color: transparent; + } + 10.1%, 35%{ + border-bottom-color: currentColor; + } + 50.1%{ + border-left-color: transparent; + } + 100% { + border-left-color: transparent; + border-bottom-color: transparent; + transform: rotate(360deg); + } + } +} + +.loadUIOverrides(); diff --git a/semantic/src/definitions/elements/placeholder.less b/semantic/src/definitions/elements/placeholder.less new file mode 100644 index 0000000..5440612 --- /dev/null +++ b/semantic/src/definitions/elements/placeholder.less @@ -0,0 +1,248 @@ +/*! + * # Fomantic-UI - Loader + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ +/******************************* + Theme +*******************************/ + +@type : 'element'; +@element : 'placeholder'; + +@import (multiple) '../../theme.config'; + +/*------------------- + Content +--------------------*/ + +.ui.placeholder { + position: static; + overflow: hidden; + animation: placeholderShimmer @placeholderLoadingAnimationDuration linear; + animation-iteration-count: infinite; + background-color: @white; + background-image: @placeholderLoadingGradient; + background-size: @placeholderLoadingGradientWidth 100%; + max-width: @placeholderMaxWidth; +} + +@keyframes placeholderShimmer{ + 0% { + background-position: -@placeholderLoadingGradientWidth 0 + } + 100% { + background-position: @placeholderLoadingGradientWidth 0 + } +} + +.ui.placeholder + .ui.placeholder { + margin-top: @consecutivePlaceholderSpacing; +} +.ui.placeholder + .ui.placeholder { + animation-delay: @placeholderAnimationInterval; +} +.ui.placeholder + .ui.placeholder + .ui.placeholder { + animation-delay: (@placeholderAnimationInterval * 2); +} +.ui.placeholder + .ui.placeholder + .ui.placeholder + .ui.placeholder { + animation-delay: (@placeholderAnimationInterval * 3); +} +.ui.placeholder + .ui.placeholder + .ui.placeholder + .ui.placeholder + .ui.placeholder { + animation-delay: (@placeholderAnimationInterval * 4); +} + +.ui.placeholder, +.ui.placeholder > :before, +.ui.placeholder .image.header:after, +.ui.placeholder .line, +.ui.placeholder .line:after { + background-color: @white; +} + +.ui.placeholder.hidden { + display:none; +} + +& when (@variationPlaceholderImage) { + /* Image */ + .ui.placeholder .image:not(.header):not(.ui):not(.icon) { + height: @placeholderImageHeight; + } + .ui.placeholder .square.image:not(.header) { + height: 0; + overflow: hidden; + /* 1/1 aspect ratio */ + padding-top: 100%; + } + .ui.placeholder .rectangular.image:not(.header) { + height: 0; + overflow: hidden; + /* 4/3 aspect ratio */ + padding-top: 75%; + } +} + +& when (@variationPlaceholderLine) or (@variationPlaceholderHeader) { + /* Lines */ + .ui.placeholder .line { + position: relative; + height: @placeholderLineMargin; + } + .ui.placeholder .line:before, + .ui.placeholder .line:after { + top: 100%; + position: absolute; + content: ''; + background-color: inherit; + } + .ui.placeholder .line:before { + left: 0; + } + .ui.placeholder .line:after { + right: 0; + } + + /* Any Lines */ + .ui.placeholder .line { + margin-bottom: @placeholderLineHeight; + } + .ui.placeholder .line:before, + .ui.placeholder .line:after { + height: @placeholderLineHeight; + } + .ui.placeholder .line:not(:first-child) { + margin-top: @placeholderLineHeight; + } + + /* Line Outdent */ + .ui.placeholder .line:nth-child(1):after { + width: @placeholderLineOneOutdent; + } + .ui.placeholder .line:nth-child(2):after { + width: @placeholderLineTwoOutdent; + } + .ui.placeholder .line:nth-child(3):after { + width: @placeholderLineThreeOutdent; + } + .ui.placeholder .line:nth-child(4):after { + width: @placeholderLineFourOutdent; + } + .ui.placeholder .line:nth-child(5):after { + width: @placeholderLineFiveOutdent; + } +} + +& when (@variationPlaceholderHeader) { + /* Header Image + 2 Lines */ + .ui.placeholder .header { + position: relative; + overflow: hidden; + } + /* Header Line 1 & 2*/ + .ui.placeholder .header .line { + margin-bottom: @placeholderHeaderLineHeight; + } + .ui.placeholder .header .line:before, + .ui.placeholder .header .line:after { + height: @placeholderHeaderLineHeight; + } + .ui.placeholder .header .line:not(:first-child) { + margin-top: @placeholderHeaderLineHeight; + } + .ui.placeholder .header .line:after { + width: @placeholderHeaderLineOneOutdent; + } + .ui.placeholder .header .line:nth-child(2):after { + width: @placeholderHeaderLineTwoOutdent; + } + + & when (@variationPlaceholderImage) { + /* Image Header */ + .ui.placeholder .image.header .line { + margin-left: @placeholderImageWidth; + } + .ui.placeholder .image.header .line:before { + width: @placeholderImageTextIndent; + } + .ui.placeholder .image.header:after { + display: block; + height: @placeholderLineMargin; + content: ''; + margin-left: @placeholderImageWidth; + } + } +} + +/* Spacing */ +.ui.placeholder .image .line:first-child, +.ui.placeholder .paragraph .line:first-child, +.ui.placeholder .header .line:first-child { + height: 0.01px; +} +.ui.placeholder .image:not(:first-child):before, +.ui.placeholder .paragraph:not(:first-child):before, +.ui.placeholder .header:not(:first-child):before { + height: @placeholderSpacing; + content: ''; + display: block; +} + +& when (@variationPlaceholderInverted) { + /* Inverted Content Loader */ + .ui.inverted.placeholder { + background-image: @placeholderInvertedLoadingGradient; + } + .ui.inverted.placeholder, + .ui.inverted.placeholder > :before, + .ui.inverted.placeholder .image.header:after, + .ui.inverted.placeholder .line, + .ui.inverted.placeholder .line:after { + background-color: @black; + } +} + +/******************************* + Variations +*******************************/ + + +/*------------------- + Sizes +--------------------*/ +& when (@variationPlaceholderLengths) { + .ui.placeholder .full.line.line.line:after { + width: @placeholderFullLineOutdent; + } + .ui.placeholder .very.long.line.line.line:after { + width: @placeholderVeryLongLineOutdent; + } + .ui.placeholder .long.line.line.line:after { + width: @placeholderLongLineOutdent; + } + .ui.placeholder .medium.line.line.line:after { + width: @placeholderMediumLineOutdent; + } + .ui.placeholder .short.line.line.line:after { + width: @placeholderShortLineOutdent; + } + .ui.placeholder .very.short.line.line.line:after { + width: @placeholderVeryShortLineOutdent; + } +} + +& when (@variationPlaceholderFluid) { + /*------------------- + Fluid + --------------------*/ + + .ui.fluid.placeholder { + max-width: none; + } +} + +.loadUIOverrides(); diff --git a/semantic/src/definitions/elements/rail.less b/semantic/src/definitions/elements/rail.less new file mode 100644 index 0000000..d7ffc51 --- /dev/null +++ b/semantic/src/definitions/elements/rail.less @@ -0,0 +1,147 @@ +/*! + * # Fomantic-UI - Rail + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +/******************************* + Theme +*******************************/ + +@type : 'element'; +@element : 'rail'; + +@import (multiple) '../../theme.config'; + +/******************************* + Rails +*******************************/ + +.ui.rail { + position: absolute; + top: 0; + width: @width; + height: @height; +} + +.ui.left.rail { + left: auto; + right: 100%; + padding: 0 @splitDistance 0 0; + margin: 0 @splitDistance 0 0; +} + +.ui.right.rail { + left: 100%; + right: auto; + padding: 0 0 0 @splitDistance; + margin: 0 0 0 @splitDistance; +} + +/******************************* + Variations +*******************************/ + +& when (@variationRailInternal) { + /*-------------- + Internal + ---------------*/ + + .ui.left.internal.rail { + left: 0; + right: auto; + padding: 0 0 0 @splitDistance; + margin: 0 0 0 @splitDistance; + } + + .ui.right.internal.rail { + left: auto; + right: 0; + padding: 0 @splitDistance 0 0; + margin: 0 @splitDistance 0 0; + } +} + +& when (@variationRailDividing) { + /*-------------- + Dividing + ---------------*/ + + .ui.dividing.rail { + width: @dividingWidth; + } + .ui.left.dividing.rail { + padding: 0 @splitDividingDistance 0 0; + margin: 0 @splitDividingDistance 0 0; + border-right: @dividingBorder; + } + .ui.right.dividing.rail { + border-left: @dividingBorder; + padding: 0 0 0 @splitDividingDistance; + margin: 0 0 0 @splitDividingDistance; + } +} + +& when (@variationRailDistance) { + /*-------------- + Distance + ---------------*/ + + .ui.close.rail { + width: @closeWidth; + } + .ui.close.left.rail { + padding: 0 @splitCloseDistance 0 0; + margin: 0 @splitCloseDistance 0 0; + } + .ui.close.right.rail { + padding: 0 0 0 @splitCloseDistance; + margin: 0 0 0 @splitCloseDistance; + } + + .ui.very.close.rail { + width: @veryCloseWidth; + } + .ui.very.close.left.rail { + padding: 0 @splitVeryCloseDistance 0 0; + margin: 0 @splitVeryCloseDistance 0 0; + } + .ui.very.close.right.rail { + padding: 0 0 0 @splitVeryCloseDistance; + margin: 0 0 0 @splitVeryCloseDistance; + } +} + +& when (@variationRailAttached) { + /*-------------- + Attached + ---------------*/ + + .ui.attached.left.rail, + .ui.attached.right.rail { + padding: 0; + margin: 0; + } +} + +/*-------------- + Sizing +---------------*/ + +.ui.rail { + font-size: @medium; +} +& when not (@variationRailSizes = false) { + each(@variationRailSizes, { + @s: @@value; + .ui.@{value}.rail { + font-size: @s; + } + }) +} + +.loadUIOverrides(); diff --git a/semantic/src/definitions/elements/reveal.less b/semantic/src/definitions/elements/reveal.less new file mode 100644 index 0000000..839668e --- /dev/null +++ b/semantic/src/definitions/elements/reveal.less @@ -0,0 +1,289 @@ +/*! + * # Fomantic-UI - Reveal + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +/******************************* + Theme +*******************************/ + +@type : 'element'; +@element : 'reveal'; + +@import (multiple) '../../theme.config'; + +/******************************* + Reveal +*******************************/ + +.ui.reveal { + display: inherit; + position: relative !important; + font-size: 0; +} + +.ui.reveal > .visible.content { + position: absolute !important; + top: 0 !important; + left: 0 !important; + z-index: @topZIndex !important; + transition: @transition; +} +.ui.reveal > .hidden.content { + position: relative !important; + z-index: @bottomZIndex !important; +} + +/* Make sure hovered element is on top of other reveal */ +.ui.active.reveal .visible.content, +.ui.reveal:hover .visible.content { + z-index: @activeZIndex !important; +} + + +/******************************* + Types +*******************************/ + +& when (@variationRevealSlide) { + /*-------------- + Slide + ---------------*/ + + .ui.slide.reveal { + position: relative !important; + overflow: hidden !important; + white-space: nowrap; + } + + .ui.slide.reveal > .content { + display: block; + width: 100%; + white-space: normal; + float: left; + + margin: 0; + transition: @slideTransition; + } + + .ui.slide.reveal > .visible.content { + position: relative !important; + } + .ui.slide.reveal > .hidden.content { + position: absolute !important; + left: 0 !important; + width: 100% !important; + transform: translateX(100%) !important; + } + .ui.slide.active.reveal > .visible.content, + .ui.slide.reveal:hover > .visible.content { + transform: translateX(-100%) !important; + } + .ui.slide.active.reveal > .hidden.content, + .ui.slide.reveal:hover > .hidden.content { + transform: translateX(0%) !important; + } + + .ui.slide.right.reveal > .visible.content { + transform: translateX(0%) !important; + } + .ui.slide.right.reveal > .hidden.content { + transform: translateX(-100%) !important; + } + .ui.slide.right.active.reveal > .visible.content, + .ui.slide.right.reveal:hover > .visible.content { + transform: translateX(100%) !important; + } + .ui.slide.right.active.reveal > .hidden.content, + .ui.slide.right.reveal:hover > .hidden.content { + transform: translateX(0%) !important; + } + + .ui.slide.up.reveal > .hidden.content { + transform: translateY(100%) !important; + } + .ui.slide.up.active.reveal > .visible.content, + .ui.slide.up.reveal:hover > .visible.content { + transform: translateY(-100%) !important; + } + .ui.slide.up.active.reveal > .hidden.content, + .ui.slide.up.reveal:hover > .hidden.content { + transform: translateY(0%) !important; + } + + .ui.slide.down.reveal > .hidden.content { + transform: translateY(-100%) !important; + } + .ui.slide.down.active.reveal > .visible.content, + .ui.slide.down.reveal:hover > .visible.content { + transform: translateY(100%) !important; + } + .ui.slide.down.active.reveal > .hidden.content, + .ui.slide.down.reveal:hover > .hidden.content { + transform: translateY(0%) !important; + } +} + +& when (@variationRevealFade) { + /*-------------- + Fade + ---------------*/ + + .ui.fade.reveal > .visible.content { + opacity: 1; + } + .ui.fade.active.reveal > .visible.content, + .ui.fade.reveal:hover > .visible.content { + opacity: 0; + } +} + +& when (@variationRevealMove) { + /*-------------- + Move + ---------------*/ + + .ui.move.reveal { + position: relative !important; + overflow: hidden !important; + white-space: nowrap; + } + + .ui.move.reveal > .content { + display: block; + float: left; + white-space: normal; + + margin: 0; + transition: @moveTransition; + } + + .ui.move.reveal > .visible.content { + position: relative !important; + } + .ui.move.reveal > .hidden.content { + position: absolute !important; + left: 0 !important; + width: 100% !important; + } + .ui.move.active.reveal > .visible.content, + .ui.move.reveal:hover > .visible.content { + transform: translateX(-100%) !important; + } + .ui.move.right.active.reveal > .visible.content, + .ui.move.right.reveal:hover > .visible.content { + transform: translateX(100%) !important; + } + .ui.move.up.active.reveal > .visible.content, + .ui.move.up.reveal:hover > .visible.content { + transform: translateY(-100%) !important; + } + .ui.move.down.active.reveal > .visible.content, + .ui.move.down.reveal:hover > .visible.content { + transform: translateY(100%) !important; + } +} + + +& when (@variationRevealRotate) { + /*-------------- + Rotate + ---------------*/ + + .ui.rotate.reveal > .visible.content { + transition-duration: @transitionDuration; + transform: rotate(0deg); + } + + .ui.rotate.reveal > .visible.content, + .ui.rotate.right.reveal > .visible.content { + transform-origin: bottom right; + } + .ui.rotate.active.reveal > .visible.content, + .ui.rotate.reveal:hover > .visible.content, + .ui.rotate.right.active.reveal > .visible.content, + .ui.rotate.right.reveal:hover > .visible.content { + transform: rotate(@rotateDegrees); + } + + .ui.rotate.left.reveal > .visible.content { + transform-origin: bottom left; + } + .ui.rotate.left.active.reveal > .visible.content, + .ui.rotate.left.reveal:hover > .visible.content { + transform: rotate(-@rotateDegrees); + } +} + +/******************************* + States +*******************************/ + +& when (@variationRevealDisabled) { + .ui.disabled.reveal:hover > .visible.visible.content { + position: static !important; + display: block !important; + opacity: 1 !important; + top: 0 !important; + left: 0 !important; + right: auto !important; + bottom: auto !important; + transform: none !important; + } + .ui.disabled.reveal:hover > .hidden.hidden.content { + display: none !important; + } +} + + +/******************************* + Coupling +*******************************/ + +.ui.reveal > .ui.ribbon.label { + z-index: @overlayZIndex; +} + +/******************************* + Variations +*******************************/ + +/*-------------- + Visible +---------------*/ + +.ui.visible.reveal { + overflow: visible; +} + +/*-------------- + Instant +---------------*/ + +.ui.instant.reveal > .content { + transition-delay: 0s !important; +} + + +/*-------------- + Sizing +---------------*/ + +.ui.reveal > .content { + font-size: @medium; +} +& when not (@variationRevealSizes = false) { + each(@variationRevealSizes, { + @s: @@value; + .ui.@{value}.reveal > .content { + font-size: @s; + } + }) +} + +.loadUIOverrides(); diff --git a/semantic/src/definitions/elements/segment.less b/semantic/src/definitions/elements/segment.less new file mode 100644 index 0000000..ec5e19b --- /dev/null +++ b/semantic/src/definitions/elements/segment.less @@ -0,0 +1,774 @@ +/*! + * # Fomantic-UI - Segment + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +/******************************* + Theme +*******************************/ + +@type : 'element'; +@element : 'segment'; + +@import (multiple) '../../theme.config'; + +/******************************* + Segment +*******************************/ + +.ui.segment { + position: relative; + background: @background; + box-shadow: @boxShadow; + margin: @margin; + padding: @padding; + border-radius: @borderRadius; + border: @border; +} + +.ui.segment:first-child { + margin-top: 0; +} +.ui.segment:last-child { + margin-bottom: 0; +} + +& when (@variationSegmentVertical) { + /* Vertical */ + .ui.vertical.segment { + margin: 0; + padding-left: 0; + padding-right: 0; + + background: none transparent; + border-radius: 0; + box-shadow: none; + border: none; + border-bottom: @borderWidth solid @borderColor; + } + .ui.vertical.segment:last-child { + border-bottom: none; + } +} + + +/*------------------- + Loose Coupling +--------------------*/ +& when (@variationSegmentInverted) { + /* Header */ + .ui.inverted.segment > .ui.header .sub.header, + .ui.inverted.segment > .ui.header { + color: @white; + } +} + +& when (@variationSegmentAttached) { + /* Label */ + .ui[class*="bottom attached"].segment > [class*="top attached"].label { + border-top-left-radius: 0; + border-top-right-radius: 0; + } + .ui[class*="top attached"].segment > [class*="bottom attached"].label { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } + .ui.attached.segment:not(.top):not(.bottom) > [class*="top attached"].label { + border-top-left-radius: 0; + border-top-right-radius: 0; + } + .ui.attached.segment:not(.top):not(.bottom) > [class*="bottom attached"].label { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } +} + +/* Grid */ +.ui.page.grid.segment, +.ui.grid > .row > .ui.segment.column, +.ui.grid > .ui.segment.column { + padding-top: @pageGridMargin; + padding-bottom: @pageGridMargin; +} +.ui.grid.segment { + margin: @margin; + border-radius: @borderRadius; +} + +/* Table */ +.ui.basic.table.segment { + background: @background; + border: @border; + box-shadow: @boxShadow; +} +.ui[class*="very basic"].table.segment { + padding: @padding; +} + +/* Tab */ +.ui.segment.tab:last-child { + margin-bottom: @verticalMargin; +} + +/******************************* + Types +*******************************/ + +& when (@variationSegmentPlaceholder) { + /*------------------- + Placeholder + --------------------*/ + + .ui.placeholder.segment { + display: flex; + flex-direction: column; + justify-content: center; + align-items: stretch; + max-width: initial; + animation: none; + overflow: visible; + padding: @placeholderPadding; + min-height: @placeholderMinHeight; + background: @placeholderBackground; + border-color: @placeholderBorderColor; + box-shadow: @placeholderBoxShadow; + } + + .ui.placeholder.segment .button, + .ui.placeholder.segment textarea { + display: block; + } + .ui.placeholder.segment .field, + .ui.placeholder.segment textarea, + .ui.placeholder.segment > .ui.input, + .ui.placeholder.segment .button { + max-width: @placeholderContentMaxWidth; + margin-left: auto; + margin-right: auto; + } + .ui.placeholder.segment .column .button, + .ui.placeholder.segment .column .field, + .ui.placeholder.segment .column textarea, + .ui.placeholder.segment .column > .ui.input { + max-width: @placeholderContentMaxWidth; + margin-left: auto; + margin-right: auto; + } + + .ui.placeholder.segment > .inline { + align-self: center; + } + .ui.placeholder.segment > .inline > .button { + display: inline-block; + width: auto; + margin: @placeholderContentInlineButtonMargin; + } + .ui.placeholder.segment > .inline > .button:last-child { + margin-right: 0; + } +} + +& when (@variationSegmentPiled) { + /*------------------- + Piled + --------------------*/ + + .ui.piled.segments, + .ui.piled.segment { + margin: @piledMargin 0; + box-shadow: @piledBoxShadow; + z-index: @piledZIndex; + } + .ui.piled.segment:first-child { + margin-top: 0; + } + .ui.piled.segment:last-child { + margin-bottom: 0; + } + .ui.piled.segments:after, + .ui.piled.segments:before, + .ui.piled.segment:after, + .ui.piled.segment:before { + background-color: @white; + visibility: visible; + content: ''; + display: block; + height: 100%; + left: 0; + position: absolute; + width: 100%; + border: @piledBorder; + box-shadow: @piledBoxShadow; + } + .ui.piled.segments:before, + .ui.piled.segment:before { + transform: rotate(-@piledDegrees); + top: 0; + z-index: -2; + } + .ui.piled.segments:after, + .ui.piled.segment:after { + transform: rotate(@piledDegrees); + top: 0; + z-index: -1; + } + & when (@variationSegmentAttached) { + /* Piled Attached */ + .ui[class*="top attached"].piled.segment { + margin-top: @piledMargin; + margin-bottom: 0; + } + .ui.piled.segment[class*="top attached"]:first-child { + margin-top: 0; + } + .ui.piled.segment[class*="bottom attached"] { + margin-top: 0; + margin-bottom: @piledMargin; + } + .ui.piled.segment[class*="bottom attached"]:last-child { + margin-bottom: 0; + } + } +} + +& when (@variationSegmentStacked) { + /*------------------- + Stacked + --------------------*/ + + .ui.stacked.segment { + padding-bottom: @stackedPadding; + } + .ui.stacked.segments:before, + .ui.stacked.segments:after, + .ui.stacked.segment:before, + .ui.stacked.segment:after { + content: ''; + position: absolute; + bottom: -(@stackedHeight / 2); + left: 0; + + border-top: 1px solid @borderColor; + background: @stackedPageBackground; + + width: 100%; + height: @stackedHeight; + visibility: visible; + } + .ui.stacked.segments:before, + .ui.stacked.segment:before { + display: none; + } + + /* Add additional page */ + .ui.tall.stacked.segments:before, + .ui.tall.stacked.segment:before { + display: block; + bottom: 0; + } + & when (@variationSegmentInverted) { + /* Inverted */ + .ui.stacked.inverted.segments:before, + .ui.stacked.inverted.segments:after, + .ui.stacked.inverted.segment:before, + .ui.stacked.inverted.segment:after { + background-color: @subtleTransparentBlack; + border-top: 1px solid @selectedBorderColor; + } + } +} + +& when (@variationSegmentPadded) { + /*------------------- + Padded + --------------------*/ + + .ui.padded.segment { + padding: @paddedSegmentPadding; + } + + .ui[class*="very padded"].segment { + padding: @veryPaddedSegmentPadding; + } + + & when (@variationSegmentVertical) { + /* Padded vertical */ + .ui.padded.segment.vertical.segment, + .ui[class*="very padded"].vertical.segment { + padding-left: 0; + padding-right: 0; + } + } +} + +& when (@variationSegmentCompact) { + /*------------------- + Compact + --------------------*/ + + .ui.compact.segment { + display: table; + } + + /* Compact Group */ + .ui.compact.segments { + display: inline-flex; + } + .ui.compact.segments .segment, + .ui.segments .compact.segment { + display: block; + flex: 0 1 auto; + } +} + +& when (@variationSegmentCircular) { + /*------------------- + Circular + --------------------*/ + + .ui.circular.segment { + display: table-cell; + padding: @circularPadding; + text-align: center; + vertical-align: middle; + border-radius: 500em; + } +} + +& when (@variationSegmentRaised) { + /*------------------- + Raised + --------------------*/ + + .ui.raised.raised.segments, + .ui.raised.raised.segment { + box-shadow: @raisedBoxShadow; + } +} + +& when (@variationSegmentGroups) { + /******************************* + Groups + *******************************/ + + /* Group */ + .ui.segments { + flex-direction: column; + position: relative; + margin: @groupedMargin; + border: @groupedBorder; + box-shadow: @groupedBoxShadow; + border-radius: @groupedBorderRadius; + } + .ui.segments:first-child { + margin-top: 0; + } + .ui.segments:last-child { + margin-bottom: 0; + } + + + /* Nested Segment */ + .ui.segments > .segment { + top: 0; + bottom: 0; + border-radius: 0; + margin: @groupedSegmentMargin; + width: @groupedSegmentWidth; + box-shadow: @groupedSegmentBoxShadow; + border: @groupedSegmentBorder; + border-top: @groupedSegmentDivider; + } + + .ui.segments:not(.horizontal) > .segment:first-child { + top: @attachedTopOffset; + bottom: 0; + border-top: none; + margin-top: 0; + margin-bottom: 0; + border-radius: @borderRadius @borderRadius 0 0; + } + + /* Bottom */ + .ui.segments:not(.horizontal) > .segment:last-child { + top: @attachedBottomOffset; + bottom: 0; + margin-top: 0; + margin-bottom: 0; + box-shadow: @attachedBottomBoxShadow; + border-radius: 0 0 @borderRadius @borderRadius; + } + + /* Only */ + .ui.segments:not(.horizontal) > .segment:only-child { + border-radius: @borderRadius; + } + + + /* Nested Group */ + .ui.segments > .ui.segments { + border-top: @groupedSegmentDivider; + margin: @nestedGroupMargin; + } + .ui.segments > .segments:first-child { + border-top: none; + } + .ui.segments > .segment + .segments:not(.horizontal) { + margin-top: 0; + } + + & when (@variationSegmentHorizontal) { + /* Horizontal Group */ + .ui.horizontal.segments { + display: flex; + flex-direction: row; + background-color: transparent; + padding: 0; + box-shadow: @boxShadow; + margin: @margin; + border-radius: @borderRadius; + border: @border; + } + .ui.stackable.horizontal.segments { + flex-wrap: wrap; + } + + /* Nested Horizontal Group */ + .ui.segments > .horizontal.segments { + margin: 0; + background-color: transparent; + border-radius: 0; + border: none; + box-shadow: none; + border-top: @groupedSegmentDivider; + } + + /* Horizontal Segment */ + .ui.horizontal.segments:not(.compact) > .segment:not(.compact) { + flex: 1 1 auto; + -ms-flex: 1 1 0; /* Solves #2550 MS Flex */ + } + .ui.horizontal.segments > .segment { + margin: 0; + min-width: 0; + border-radius: 0; + border: none; + box-shadow: none; + border-left: @borderWidth solid @borderColor; + } + + /* Border Fixes */ + .ui.segments > .horizontal.segments:first-child { + border-top: none; + } + .ui.horizontal.segments:not(.stackable) > .segment:first-child { + border-left: none; + } + .ui.horizontal.segments > .segment:first-child { + border-radius: @borderRadius 0 0 @borderRadius; + } + .ui.horizontal.segments > .segment:last-child { + border-radius: 0 @borderRadius @borderRadius 0; + } + } +} + + +/******************************* + States +*******************************/ + +& when (@variationSegmentDisabled) { + /*-------------- + Disabled + ---------------*/ + + .ui.disabled.segment { + opacity: @disabledOpacity; + color: @disabledTextColor; + } +} + +& when (@variationSegmentLoading) { + /*-------------- + Loading + ---------------*/ + + .ui.loading.segment { + position: relative; + cursor: default; + pointer-events: none; + text-shadow: none !important; + transition: all 0s linear; + } + .ui.loading.segment:before { + position: absolute; + content: ''; + top: 0; + left: 0; + background: @loaderDimmerColor; + width: 100%; + height: 100%; + border-radius: @borderRadius; + z-index: @loaderDimmerZIndex; + } + .ui.loading.segment:after { + position: absolute; + content: ''; + top: 50%; + left: 50%; + + margin: @loaderMargin; + width: @loaderSize; + height: @loaderSize; + + animation: loader @loaderSpeed infinite linear; + border: @loaderLineWidth solid @loaderLineColor; + border-radius: @circularRadius; + + box-shadow: 0 0 0 1px transparent; + visibility: visible; + z-index: @loaderLineZIndex; + } +} + + + +/******************************* + Variations +*******************************/ + +& when (@variationSegmentBasic) { + /*------------------- + Basic + --------------------*/ + + .ui.basic.segment, + .ui.segments .ui.basic.segment, + .ui.basic.segments { + background: @basicBackground; + box-shadow: @basicBoxShadow; + border: @basicBorder; + border-radius: @basicBorderRadius; + } +} + +& when (@variationSegmentClearing) { + /*------------------- + Clearing + --------------------*/ + + .ui.clearing.segment:after { + content: ""; + display: block; + clear: both; + } +} + +/*------------------- + Colors +--------------------*/ + +each(@colors,{ + @color: replace(@key,'@',''); + @c: @colors[@@color][color]; + & when not (@color=primary) and not (@color=secondary) { + .ui.@{color}.segment.segment.segment.segment.segment:not(.inverted) { + border-top: @coloredBorderSize solid @c; + } + & when (@variationSegmentInverted) { + .ui.inverted.@{color}.segment.segment.segment.segment.segment { + background-color: @c; + color: @white; + } + } + } +}) + +& when (@variationSegmentAligned) { + /*------------------- + Aligned + --------------------*/ + + .ui[class*="left aligned"].segment { + text-align: left; + } + .ui[class*="right aligned"].segment { + text-align: right; + } + .ui[class*="center aligned"].segment { + text-align: center; + } +} + +& when (@variationSegmentFloating) { + /*------------------- + Floated + --------------------*/ + + .ui.floated.segment, + .ui[class*="left floated"].segment { + float: left; + margin-right: @floatedDistance; + } + .ui[class*="right floated"].segment { + float: right; + margin-left: @floatedDistance; + } +} + +& when (@variationSegmentInverted) { + /*------------------- + Inverted + --------------------*/ + + .ui.inverted.segment { + border: none; + box-shadow: none; + } + .ui.inverted.segment, + .ui.primary.inverted.segment { + background: @invertedBackground; + color: @invertedTextColor; + } + + /* Nested */ + .ui.inverted.segment .segment { + color: @textColor; + } + .ui.inverted.segment .inverted.segment { + color: @invertedTextColor; + } + & when (@variationSegmentAttached) { + /* Attached */ + .ui.inverted.attached.segment { + border-color: @solidWhiteBorderColor; + } + } + & when (@variationSegmentLoading) { + /* Loading */ + .ui.inverted.loading.segment { + color: @invertedLoaderLineColor; + } + .ui.inverted.loading.segment:before { + background: @loaderInvertedDimmerColor; + } + } +} + +/*------------------- + Emphasis +--------------------*/ +& when (@variationSegmentSecondary) { + /* Secondary */ + .ui.secondary.segment { + background: @secondaryBackground; + color: @secondaryColor; + } + & when (@variationSegmentInverted) { + .ui.secondary.inverted.segment { + background: @secondaryInvertedBackground; + color: @secondaryInvertedColor; + } + } +} + +& when (@variationSegmentTertiary) { + /* Tertiary */ + .ui.tertiary.segment { + background: @tertiaryBackground; + color: @tertiaryColor; + } + & when (@variationSegmentInverted) { + .ui.tertiary.inverted.segment { + background: @tertiaryInvertedBackground; + color: @tertiaryInvertedColor; + } + } +} + +& when (@variationSegmentAttached) { + /*------------------- + Attached + --------------------*/ + + /* Middle */ + .ui.attached.segment { + top: 0; + bottom: 0; + border-radius: 0; + margin: 0 @attachedHorizontalOffset; + width: @attachedWidth; + max-width: @attachedWidth; + box-shadow: @attachedBoxShadow; + border: @attachedBorder; + } + .ui.attached:not(.message) + .ui.attached.segment:not(.top) { + border-top: none; + } + + /* Top */ + .ui[class*="top attached"].segment { + bottom: 0; + margin-bottom: 0; + top: @attachedTopOffset; + margin-top: @verticalMargin; + border-radius: @borderRadius @borderRadius 0 0; + } + .ui.segment[class*="top attached"]:first-child { + margin-top: 0; + } + + /* Bottom */ + .ui.segment[class*="bottom attached"] { + bottom: 0; + margin-top: 0; + top: @attachedBottomOffset; + margin-bottom: @verticalMargin; + box-shadow: @attachedBottomBoxShadow; + border-radius: 0 0 @borderRadius @borderRadius; + } + .ui.segment[class*="bottom attached"]:last-child { + margin-bottom: @verticalMargin; + } +} + +& when (@variationSegmentFitted) { + /*-------------- + Fitted + ---------------*/ + + .ui.fitted.segment:not(.horizontally) { + padding-top: 0; + padding-bottom: 0; + } + .ui.fitted.segment:not(.vertically) { + padding-left: 0; + padding-right: 0; + } +} + +/*------------------- + Size +--------------------*/ + +.ui.segments .segment, +.ui.segment { + font-size: @medium; +} +& when not (@variationSegmentSizes = false) { + each(@variationSegmentSizes, { + @s: @@value; + .ui.@{value}.segments .segment, + .ui.@{value}.segment { + font-size: @s; + } + }) +} + +.loadUIOverrides(); diff --git a/semantic/src/definitions/elements/step.less b/semantic/src/definitions/elements/step.less new file mode 100644 index 0000000..fa339e8 --- /dev/null +++ b/semantic/src/definitions/elements/step.less @@ -0,0 +1,630 @@ +/*! + * # Fomantic-UI - Step + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + + +/******************************* + Step +*******************************/ + +/*-------------- + Load Theme +---------------*/ + +@type : 'element'; +@element : 'step'; + +@import (multiple) '../../theme.config'; + +/******************************* + Plural +*******************************/ + +.ui.steps { + display: inline-flex; + flex-direction: row; + align-items: stretch; + margin: @stepMargin; + background: @stepsBackground; + box-shadow: @stepsBoxShadow; + line-height: @lineHeight; + border-radius: @stepsBorderRadius; + border: @stepsBorder; +} +.ui.steps:not(.unstackable) { + flex-wrap: wrap; +} + +/* First Steps */ +.ui.steps:first-child { + margin-top: 0; +} + +/* Last Steps */ +.ui.steps:last-child { + margin-bottom: 0; +} + + +/******************************* + Singular +*******************************/ + +.ui.steps .step { + position: relative; + display: flex; + flex: 1 0 auto; + flex-wrap: wrap; + flex-direction: row; + vertical-align: middle; + align-items: center; + justify-content: @justifyContent; + + margin: @verticalMargin @horizontalMargin; + padding: @verticalPadding @horizontalPadding; + background: @background; + color: @textColor; + box-shadow: @boxShadow; + border-radius: @borderRadius; + border: @border; + border-right: @divider; + transition: @transition; +} + +/* Arrow */ +.ui.steps .step:after { + display: none; + position: absolute; + z-index: 2; + content: ''; + top: @arrowTopOffset; + right: @arrowRightOffset; + background-color: @arrowBackgroundColor; + width: @arrowSize; + height: @arrowSize; + + border-style: solid; + border-color: @borderColor; + border-width: @arrowBorderWidth; + + transition: @transition; + transform: translateY(-50%) translateX(50%) rotate(-45deg); +} + +/* First Step */ +.ui.steps .step:first-child { + padding-left: @horizontalPadding; + border-radius: @stepsBorderRadius 0 0 @stepsBorderRadius; +} + +/* Last Step */ +.ui.steps .step:last-child { + border-radius: 0 @stepsBorderRadius @stepsBorderRadius 0; + border-right: none; + margin-right: 0; +} + +/* Only Step */ +.ui.steps .step:only-child { + border-radius: @stepsBorderRadius; +} + + +/******************************* + Content +*******************************/ + +/* Title */ +.ui.steps .step .title { + font-family: @titleFontFamily; + font-size: @titleFontSize; + font-weight: @titleFontWeight; +} +.ui.steps .step > .title { + width: 100%; +} + +/* Description */ +.ui.steps .step .description { + font-weight: @descriptionFontWeight; + font-size: @descriptionFontSize; + color: @descriptionColor; +} +.ui.steps .step > .description { + width: 100%; +} +.ui.steps .step .title ~ .description { + margin-top: @descriptionDistance; +} + +/* Icon */ +.ui.steps .step > i.icon { + line-height: 1; + font-size: @iconSize; + margin: 0 @iconDistance 0 0; +} +.ui.steps .step > i.icon, +.ui.steps .step > i.icon ~ .content { + display: block; + flex: 0 1 auto; + align-self: @iconAlign; +} + +/* Horizontal Icon */ +.ui.steps:not(.vertical) .step > i.icon { + width: auto; +} + +/* Link */ +.ui.steps .link.step, +.ui.steps a.step { + cursor: pointer; +} + +/******************************* + Types +*******************************/ + +& when (@variationStepOrdered) { + /*-------------- + Ordered + ---------------*/ + + .ui.ordered.steps { + counter-reset: ordered; + } + .ui.ordered.steps .step:before { + display: block; + position: static; + text-align: center; + content: counter(ordered); + align-self: @iconAlign; + margin-right: @iconDistance; + font-size: @iconSize; + counter-increment: ordered; + font-family: @orderedFontFamily; + font-weight: @orderedFontWeight; + } + + .ui.ordered.steps .step > * { + display: block; + align-self: @iconAlign; + } +} + +& when (@variationStepVertical) { + /*-------------- + Vertical + ---------------*/ + + .ui.vertical.steps { + display: inline-flex; + flex-direction: column; + overflow: visible; + } + .ui.vertical.steps .step { + justify-content: flex-start; + border-radius: @borderRadius; + padding: @verticalPadding @horizontalPadding; + border-right: none; + border-bottom: @verticalDivider; + } + .ui.vertical.steps .step:first-child { + padding: @verticalPadding @horizontalPadding; + border-radius: @stepsBorderRadius @stepsBorderRadius 0 0; + } + .ui.vertical.steps .step:last-child { + border-bottom: none; + border-radius: 0 0 @stepsBorderRadius @stepsBorderRadius; + } + .ui.vertical.steps .step:only-child { + border-radius: @stepsBorderRadius; + } + + + /* Arrow */ + .ui.vertical.steps .step:after { + top: @verticalArrowTopOffset; + right: @verticalArrowRightOffset; + border-width: @verticalArrowBorderWidth; + display: @verticalArrowDisplay; + } + .ui.right.vertical.steps .step:after { + border-width: @verticalLeftArrowBorderWidth; + left: @verticalLeftArrowLeftOffset; + right: @verticalLeftArrowRightOffset; + transform: translateY(-50%) translateX(-50%) rotate(-45deg); + } + + .ui.vertical.steps .active.step:after { + display: @verticalActiveArrowDisplay; + } + .ui.vertical.steps .step:last-child:after { + display: @verticalLastArrowDisplay; + } + .ui.vertical.steps .active.step:last-child:after { + display: @verticalActiveLastArrowDisplay; + } +} + + +/*--------------- + Responsive +----------------*/ + +/* Mobile (Default) */ +@media only screen and (max-width: (@largestMobileScreen)) { + + .ui.steps:not(.unstackable) { + display: inline-flex; + overflow: visible; + flex-direction: column; + } + .ui.steps:not(.unstackable) .step { + width: 100% !important; + flex-direction: column; + border-radius: @borderRadius; + padding: @verticalPadding @horizontalPadding; + border-right: none; + border-bottom: @stepsBorder; + } + .ui.steps:not(.unstackable) .step:first-child { + padding: @verticalPadding @horizontalPadding; + border-radius: @stepsBorderRadius @stepsBorderRadius 0 0; + } + .ui.steps:not(.unstackable) .step:last-child { + border-radius: 0 0 @stepsBorderRadius @stepsBorderRadius; + border-bottom: none; + } + + /* Arrow */ + .ui.steps:not(.unstackable) .step:after { + top: unset; + bottom: -@arrowSize; + right: 50%; + transform: translateY(-50%) translateX(50%) rotate(45deg); + } + .ui.vertical.steps .active.step:last-child:after { + display: none; + } + /* Content */ + .ui.steps:not(.unstackable) .step .content { + text-align: center; + } + + /* Icon */ + .ui.steps:not(.unstackable) .step > i.icon, + .ui.ordered.steps:not(.unstackable) .step:before { + margin: 0 0 @mobileIconDistance 0; + } + +} + +/******************************* + States +*******************************/ + +/* Link Hover */ +.ui.steps .link.step:hover::after, +.ui.steps .link.step:hover, +.ui.steps a.step:hover::after, +.ui.steps a.step:hover { + background: @hoverBackground; + color: @hoverColor; +} + +/* Link Down */ +.ui.steps .link.step:active::after, +.ui.steps .link.step:active, +.ui.steps a.step:active::after, +.ui.steps a.step:active { + background: @downBackground; + color: @downColor; +} + +/* Active */ +.ui.steps .step.active { + cursor: auto; + background: @activeBackground; +} +.ui.steps .step.active:after { + background: @activeBackground; +} +.ui.steps .step.active .title { + color: @activeColor; +} +.ui.ordered.steps .step.active:before, +.ui.steps .active.step i.icon { + color: @activeIconColor; +} + +/* Active Arrow */ +.ui.steps .step:after { + display: @arrowDisplay; +} +.ui.steps .active.step:after { + display: @activeArrowDisplay; +} +.ui.steps .step:last-child:after { + display: @lastArrowDisplay; +} +.ui.steps .active.step:last-child:after { + display: @activeLastArrowDisplay; +} + +/* Active Hover */ +.ui.steps .link.active.step:hover::after, +.ui.steps .link.active.step:hover, +.ui.steps a.active.step:hover::after, +.ui.steps a.active.step:hover { + cursor: pointer; + background: @activeHoverBackground; + color: @activeHoverColor; +} + +/* Completed */ +.ui.steps .step.completed > i.icon:before, +.ui.ordered.steps .step.completed:before { + color: @completedColor; +} + +& when (@variationStepDisabled) { + /* Disabled */ + .ui.steps .disabled.step { + cursor: auto; + background: @disabledBackground; + pointer-events: none; + } + .ui.steps .disabled.step, + .ui.steps .disabled.step .title, + .ui.steps .disabled.step .description { + color: @disabledColor; + } + .ui.steps .disabled.step:after { + background: @disabledBackground; + } +} + + +/******************************* + Variations +*******************************/ + +& when (@variationStepStackable) { + /*-------------- + Stackable + ---------------*/ + + /* Tablet Or Below */ + @media only screen and (max-width: @largestTabletScreen) { + + .ui[class*="tablet stackable"].steps { + display: inline-flex; + overflow: visible; + flex-direction: column; + } + + /* Steps */ + .ui[class*="tablet stackable"].steps .step { + flex-direction: column; + border-radius: @borderRadius; + padding: @verticalPadding @horizontalPadding; + border-right: none; + border-bottom: @stepsBorder; + } + .ui[class*="tablet stackable"].steps .step:first-child { + padding: @verticalPadding @horizontalPadding; + border-radius: @stepsBorderRadius @stepsBorderRadius 0 0; + } + .ui[class*="tablet stackable"].steps .step:last-child { + border-radius: 0 0 @stepsBorderRadius @stepsBorderRadius; + border-bottom: none; + } + + /* Arrow */ + .ui[class*="tablet stackable"].steps .step:after { + top: unset; + bottom: -@arrowSize; + right: 50%; + transform: translateY(-50%) translateX(50%) rotate(45deg); + } + + /* Content */ + .ui[class*="tablet stackable"].steps .step .content { + text-align: center; + } + + /* Icon */ + .ui[class*="tablet stackable"].steps .step > i.icon, + .ui[class*="tablet stackable"].ordered.steps .step:before { + margin: 0 0 @mobileIconDistance 0; + } + + } +} + +& when (@variationStepFluid) { + /*-------------- + Fluid + ---------------*/ + + /* Fluid */ + .ui.fluid.steps { + display: flex; + width: 100%; + } +} + +& when (@variationStepAttached) { + /*-------------- + Attached + ---------------*/ + + /* Top */ + .ui.attached.steps { + width: @attachedWidth !important; + margin: 0 @attachedHorizontalOffset @attachedVerticalOffset; + max-width: @attachedWidth; + border-radius: @stepsBorderRadius @stepsBorderRadius 0 0; + } + .ui.attached.steps .step:first-child { + border-radius: @stepsBorderRadius 0 0 0; + } + .ui.attached.steps .step:last-child { + border-radius: 0 @stepsBorderRadius 0 0; + } + + /* Bottom */ + .ui.bottom.attached.steps { + margin: @attachedVerticalOffset @attachedHorizontalOffset 0; + border-radius: 0 0 @stepsBorderRadius @stepsBorderRadius; + } + .ui.bottom.attached.steps .step:first-child { + border-radius: 0 0 0 @stepsBorderRadius; + } + .ui.bottom.attached.steps .step:last-child { + border-radius: 0 0 @stepsBorderRadius 0; + } +} + +/*------------------- + Evenly Divided +--------------------*/ + +.ui.one.steps, +.ui.two.steps, +.ui.three.steps, +.ui.four.steps, +.ui.five.steps, +.ui.six.steps, +.ui.seven.steps, +.ui.eight.steps { + width: 100%; +} +.ui.one.steps > .step, +.ui.two.steps > .step, +.ui.three.steps > .step, +.ui.four.steps > .step, +.ui.five.steps > .step, +.ui.six.steps > .step, +.ui.seven.steps > .step, +.ui.eight.steps > .step { + flex-wrap: nowrap; +} +.ui.one.steps > .step { + width: 100%; +} +.ui.two.steps > .step { + width: 50%; +} +.ui.three.steps > .step { + width: 33.333%; +} +.ui.four.steps > .step { + width: 25%; +} +.ui.five.steps > .step { + width: 20%; +} +.ui.six.steps > .step { + width: 16.666%; +} +.ui.seven.steps > .step { + width: 14.285%; +} +.ui.eight.steps > .step { + width: 12.500%; +} + +/*------------------- + Sizes +--------------------*/ + +.ui.steps .step, +.ui.step { + font-size: @medium; +} +& when not (@variationStepSizes = false) { + each(@variationStepSizes, { + @s: @@value; + .ui.@{value}.steps .step, + .ui.@{value}.step { + font-size: @s; + } + }) +} + +& when (@variationStepInverted) { + /*-------------- + Inverted + ---------------*/ + + .ui.inverted.steps { + border: 1px solid @solidWhiteBorderColor; + } + + .ui.inverted.steps .step { + color: @invertedTextColor; + background: @black; + border-color: @solidWhiteBorderColor; + } + + .ui.inverted.steps .step:after { + background-color: @black; + border-color: @solidWhiteBorderColor; + } + + .ui.inverted.steps .step .description { + color: @invertedTextColor; + } + + /* Active */ + .ui.inverted.steps .step.active, + .ui.inverted.steps .step.active:after { + background: @invertedActiveBackground; + } + .ui.inverted.ordered.steps .step.active:before, + .ui.inverted.steps .active.step i.icon { + color: @invertedSelectedTextColor; + } + + & when (@variationStepDisabled) { + /* Disabled */ + .ui.inverted.steps .disabled.step, + .ui.inverted.steps .disabled.step:after { + background: @invertedDisabledBackground; + } + .ui.inverted.steps .disabled.step, + .ui.inverted.steps .disabled.step .title, + .ui.inverted.steps .disabled.step .description { + color: @invertedDisabledTextColor; + } + } + + /* Link Hover */ + .ui.inverted.steps .link.step:hover::after, + .ui.inverted.steps .link.step:hover, + .ui.inverted.steps a.step:hover::after, + .ui.inverted.steps a.step:hover { + background: @invertedHoverBackground; + color: @invertedHoveredTextColor; + } + + /* Link Down */ + .ui.inverted.steps .link.step:active::after, + .ui.inverted.steps .link.step:active, + .ui.inverted.steps a.step:active::after, + .ui.inverted.steps a.step:active { + background: @invertedActiveHoverBackground; + color: @invertedPressedTextColor; + } +} + + +.loadUIOverrides(); diff --git a/semantic/src/definitions/elements/text.less b/semantic/src/definitions/elements/text.less new file mode 100644 index 0000000..f2256c5 --- /dev/null +++ b/semantic/src/definitions/elements/text.less @@ -0,0 +1,74 @@ +/*! + * # Fomantic-UI - Text + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * https://github.com/fomantic/Fomantic-UI/blob/master/LICENSE.md + * + */ + + +/******************************* + Theme +*******************************/ + +@type : 'element'; +@element : 'text'; + +@import (multiple) '../../theme.config'; + + +/******************************* + Text +*******************************/ +span.ui.text { + line-height: @lineHeight; +} + +each(@colors, { + @color: replace(@key, '@', ''); + @c: @colors[@@color][color]; + @l: @colors[@@color][light]; + + span.ui.@{color}.text { + color: @c; + } + & when (@variationTextInverted) { + span.ui.inverted.@{color}.text { + color: @l; + } + } +}) + +& when (@variationTextStates) { + each(@textStates, { + @state: replace(@key, '@', ''); + @c: @textStates[@@state][color]; + + span.ui.@{state}.text { + color: @c; + } + }) +} + +& when (@variationTextDisabled) { + span.ui.disabled.text { + opacity: @disabledOpacity; + } +} + +/* Sizes */ +span.ui.medium.text { + font-size: @medium; +} +& when not (@variationTextSizes = false) { + each(@variationTextSizes, { + @s: @@value; + span.ui.@{value}.text { + font-size: @s; + } + }) +} + +.loadUIOverrides(); diff --git a/semantic/src/definitions/globals/reset.less b/semantic/src/definitions/globals/reset.less new file mode 100644 index 0000000..1ebcf6b --- /dev/null +++ b/semantic/src/definitions/globals/reset.less @@ -0,0 +1,40 @@ +/*! + * # Fomantic-UI - Reset + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +/******************************* + Theme +*******************************/ + +@type : 'global'; +@element : 'reset'; + +@import (multiple) '../../theme.config'; + +/******************************* + Reset +*******************************/ + +/* Border-Box */ +*, +*:before, +*:after { + box-sizing: inherit; +} +html { + box-sizing: border-box; +} + +/* iPad Input Shadows */ +input[type="text"], input[type="email"], input[type="search"], input[type="password"] { + -webkit-appearance: none; + -moz-appearance: none; /* mobile firefox too! */ +} + +.loadUIOverrides(); diff --git a/semantic/src/definitions/globals/site.js b/semantic/src/definitions/globals/site.js new file mode 100644 index 0000000..bc53e9f --- /dev/null +++ b/semantic/src/definitions/globals/site.js @@ -0,0 +1,493 @@ +/*! + * # Fomantic-UI - Site + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +$.isFunction = $.isFunction || function(obj) { + return typeof obj === "function" && typeof obj.nodeType !== "number"; +}; + +$.site = $.fn.site = function(parameters) { + var + time = new Date().getTime(), + performance = [], + + query = arguments[0], + methodInvoked = (typeof query == 'string'), + queryArguments = [].slice.call(arguments, 1), + + settings = ( $.isPlainObject(parameters) ) + ? $.extend(true, {}, $.site.settings, parameters) + : $.extend({}, $.site.settings), + + namespace = settings.namespace, + error = settings.error, + + moduleNamespace = 'module-' + namespace, + + $document = $(document), + $module = $document, + element = this, + instance = $module.data(moduleNamespace), + + module, + returnedValue + ; + module = { + + initialize: function() { + module.instantiate(); + }, + + instantiate: function() { + module.verbose('Storing instance of site', module); + instance = module; + $module + .data(moduleNamespace, module) + ; + }, + + normalize: function() { + module.fix.console(); + module.fix.requestAnimationFrame(); + }, + + fix: { + console: function() { + module.debug('Normalizing window.console'); + if (console === undefined || console.log === undefined) { + module.verbose('Console not available, normalizing events'); + module.disable.console(); + } + if (typeof console.group == 'undefined' || typeof console.groupEnd == 'undefined' || typeof console.groupCollapsed == 'undefined') { + module.verbose('Console group not available, normalizing events'); + window.console.group = function() {}; + window.console.groupEnd = function() {}; + window.console.groupCollapsed = function() {}; + } + if (typeof console.markTimeline == 'undefined') { + module.verbose('Mark timeline not available, normalizing events'); + window.console.markTimeline = function() {}; + } + }, + consoleClear: function() { + module.debug('Disabling programmatic console clearing'); + window.console.clear = function() {}; + }, + requestAnimationFrame: function() { + module.debug('Normalizing requestAnimationFrame'); + if(window.requestAnimationFrame === undefined) { + module.debug('RequestAnimationFrame not available, normalizing event'); + window.requestAnimationFrame = window.requestAnimationFrame + || window.mozRequestAnimationFrame + || window.webkitRequestAnimationFrame + || window.msRequestAnimationFrame + || function(callback) { setTimeout(callback, 0); } + ; + } + } + }, + + moduleExists: function(name) { + return ($.fn[name] !== undefined && $.fn[name].settings !== undefined); + }, + + enabled: { + modules: function(modules) { + var + enabledModules = [] + ; + modules = modules || settings.modules; + $.each(modules, function(index, name) { + if(module.moduleExists(name)) { + enabledModules.push(name); + } + }); + return enabledModules; + } + }, + + disabled: { + modules: function(modules) { + var + disabledModules = [] + ; + modules = modules || settings.modules; + $.each(modules, function(index, name) { + if(!module.moduleExists(name)) { + disabledModules.push(name); + } + }); + return disabledModules; + } + }, + + change: { + setting: function(setting, value, modules, modifyExisting) { + modules = (typeof modules === 'string') + ? (modules === 'all') + ? settings.modules + : [modules] + : modules || settings.modules + ; + modifyExisting = (modifyExisting !== undefined) + ? modifyExisting + : true + ; + $.each(modules, function(index, name) { + var + namespace = (module.moduleExists(name)) + ? $.fn[name].settings.namespace || false + : true, + $existingModules + ; + if(module.moduleExists(name)) { + module.verbose('Changing default setting', setting, value, name); + $.fn[name].settings[setting] = value; + if(modifyExisting && namespace) { + $existingModules = $(':data(module-' + namespace + ')'); + if($existingModules.length > 0) { + module.verbose('Modifying existing settings', $existingModules); + $existingModules[name]('setting', setting, value); + } + } + } + }); + }, + settings: function(newSettings, modules, modifyExisting) { + modules = (typeof modules === 'string') + ? [modules] + : modules || settings.modules + ; + modifyExisting = (modifyExisting !== undefined) + ? modifyExisting + : true + ; + $.each(modules, function(index, name) { + var + $existingModules + ; + if(module.moduleExists(name)) { + module.verbose('Changing default setting', newSettings, name); + $.extend(true, $.fn[name].settings, newSettings); + if(modifyExisting && namespace) { + $existingModules = $(':data(module-' + namespace + ')'); + if($existingModules.length > 0) { + module.verbose('Modifying existing settings', $existingModules); + $existingModules[name]('setting', newSettings); + } + } + } + }); + } + }, + + enable: { + console: function() { + module.console(true); + }, + debug: function(modules, modifyExisting) { + modules = modules || settings.modules; + module.debug('Enabling debug for modules', modules); + module.change.setting('debug', true, modules, modifyExisting); + }, + verbose: function(modules, modifyExisting) { + modules = modules || settings.modules; + module.debug('Enabling verbose debug for modules', modules); + module.change.setting('verbose', true, modules, modifyExisting); + } + }, + disable: { + console: function() { + module.console(false); + }, + debug: function(modules, modifyExisting) { + modules = modules || settings.modules; + module.debug('Disabling debug for modules', modules); + module.change.setting('debug', false, modules, modifyExisting); + }, + verbose: function(modules, modifyExisting) { + modules = modules || settings.modules; + module.debug('Disabling verbose debug for modules', modules); + module.change.setting('verbose', false, modules, modifyExisting); + } + }, + + console: function(enable) { + if(enable) { + if(instance.cache.console === undefined) { + module.error(error.console); + return; + } + module.debug('Restoring console function'); + window.console = instance.cache.console; + } + else { + module.debug('Disabling console function'); + instance.cache.console = window.console; + window.console = { + clear : function(){}, + error : function(){}, + group : function(){}, + groupCollapsed : function(){}, + groupEnd : function(){}, + info : function(){}, + log : function(){}, + markTimeline : function(){}, + warn : function(){} + }; + } + }, + + destroy: function() { + module.verbose('Destroying previous site for', $module); + $module + .removeData(moduleNamespace) + ; + }, + + cache: {}, + + setting: function(name, value) { + if( $.isPlainObject(name) ) { + $.extend(true, settings, name); + } + else if(value !== undefined) { + 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.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.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() { + 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({ + 'Element' : element, + 'Name' : message[0], + 'Arguments' : [].slice.call(message, 1) || '', + '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( (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(Array.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) { + module.destroy(); + } + module.initialize(); + } + return (returnedValue !== undefined) + ? returnedValue + : this + ; +}; + +$.site.settings = { + + name : 'Site', + namespace : 'site', + + error : { + console : 'Console cannot be restored, most likely it was overwritten outside of module', + method : 'The method you called is not defined.' + }, + + debug : false, + verbose : false, + performance : true, + + modules: [ + 'accordion', + 'api', + 'calendar', + 'checkbox', + 'dimmer', + 'dropdown', + 'embed', + 'form', + 'modal', + 'nag', + 'popup', + 'slider', + 'rating', + 'shape', + 'sidebar', + 'state', + 'sticky', + 'tab', + 'toast', + 'transition', + 'visibility', + 'visit' + ], + + siteNamespace : 'site', + namespaceStub : { + cache : {}, + config : {}, + sections : {}, + section : {}, + utilities : {} + } + +}; + +// allows for selection of elements with data attributes +$.extend($.expr[ ":" ], { + data: ($.expr.createPseudo) + ? $.expr.createPseudo(function(dataName) { + return function(elem) { + return !!$.data(elem, dataName); + }; + }) + : function(elem, i, match) { + // support: jQuery < 1.8 + return !!$.data(elem, match[ 3 ]); + } +}); + + +})( jQuery, window, document ); diff --git a/semantic/src/definitions/globals/site.less b/semantic/src/definitions/globals/site.less new file mode 100644 index 0000000..876deb3 --- /dev/null +++ b/semantic/src/definitions/globals/site.less @@ -0,0 +1,207 @@ +/*! + * # Fomantic-UI - Site + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + + +/******************************* + Theme +*******************************/ + +@type : 'global'; +@element : 'site'; + +@import (multiple) '../../theme.config'; + +/******************************* + Page +*******************************/ + +.loadFonts(); + +html, +body { + height: 100%; +} + +html { + font-size: @emSize; +} + +body { + margin: 0; + padding: 0; + overflow-x: @pageOverflowX; + min-width: @pageMinWidth; + background: @pageBackground; + font-family: @pageFont; + font-size: @fontSize; + line-height: @lineHeight; + color: @textColor; +} + +/******************************* + Headers +*******************************/ + +h1, +h2, +h3, +h4, +h5 { + font-family: @headerFont; + line-height: @headerLineHeight; + margin: @headerMargin; + font-weight: @headerFontWeight; + padding: 0; +} + +h1 { + min-height: 1rem; + font-size: @h1; +} +h2 { + font-size: @h2; +} +h3 { + font-size: @h3; +} +h4 { + font-size: @h4; +} +h5 { + font-size: @h5; +} + +h1:first-child, +h2:first-child, +h3:first-child, +h4:first-child, +h5:first-child { + margin-top: 0; +} + +h1:last-child, +h2:last-child, +h3:last-child, +h4:last-child, +h5:last-child { + margin-bottom: 0; +} + + +/******************************* + Text +*******************************/ + +p { + margin: @paragraphMargin; + line-height: @paragraphLineHeight; +} +p:first-child { + margin-top: 0; +} +p:last-child { + margin-bottom: 0; +} + +/*------------------- + Links +--------------------*/ + +a { + color: @linkColor; + text-decoration: @linkUnderline; +} +a:hover { + color: @linkHoverColor; + text-decoration: @linkHoverUnderline; +} + + +/******************************* + Scrollbars +*******************************/ + +.addScrollbars() when (@useCustomScrollbars) { + + /* Force Simple Scrollbars */ + body ::-webkit-scrollbar { + -webkit-appearance: none; + width: @customScrollbarWidth; + height: @customScrollbarHeight; + } + body ::-webkit-scrollbar-track { + background: @trackBackground; + border-radius: @trackBorderRadius; + } + body ::-webkit-scrollbar-thumb { + cursor: pointer; + border-radius: @thumbBorderRadius; + background: @thumbBackground; + transition: @thumbTransition; + } + body ::-webkit-scrollbar-thumb:window-inactive { + background: @thumbInactiveBackground; + } + body ::-webkit-scrollbar-thumb:hover { + background: @thumbHoverBackground; + } + + /* Inverted UI */ + body .ui.inverted:not(.dimmer)::-webkit-scrollbar-track { + background: @trackInvertedBackground; + } + body .ui.inverted:not(.dimmer)::-webkit-scrollbar-thumb { + background: @thumbInvertedBackground; + } + body .ui.inverted:not(.dimmer)::-webkit-scrollbar-thumb:window-inactive { + background: @thumbInvertedInactiveBackground; + } + body .ui.inverted:not(.dimmer)::-webkit-scrollbar-thumb:hover { + background: @thumbInvertedHoverBackground; + } +} + +/******************************* + Highlighting +*******************************/ + +/* Site */ +::-webkit-selection { + background-color: @highlightBackground; + color: @highlightColor; +} +::-moz-selection { + background-color: @highlightBackground; + color: @highlightColor; +} +::selection { + background-color: @highlightBackground; + color: @highlightColor; +} + +/* Form */ +textarea::-webkit-selection, +input::-webkit-selection { + background-color: @inputHighlightBackground; + color: @inputHighlightColor; +} +textarea::-moz-selection, +input::-moz-selection { + background-color: @inputHighlightBackground; + color: @inputHighlightColor; +} +textarea::selection, +input::selection { + background-color: @inputHighlightBackground; + color: @inputHighlightColor; +} + +.addScrollbars(); +.loadUIOverrides(); diff --git a/semantic/src/definitions/modules/accordion.js b/semantic/src/definitions/modules/accordion.js new file mode 100644 index 0000000..392d498 --- /dev/null +++ b/semantic/src/definitions/modules/accordion.js @@ -0,0 +1,618 @@ +/*! + * # Fomantic-UI - Accordion + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +'use strict'; + +$.isFunction = $.isFunction || function(obj) { + return typeof obj === "function" && typeof obj.nodeType !== "number"; +}; + +window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.fn.accordion = function(parameters) { + var + $allModules = $(this), + + time = new Date().getTime(), + performance = [], + + query = arguments[0], + methodInvoked = (typeof query == 'string'), + queryArguments = [].slice.call(arguments, 1), + + returnedValue + ; + $allModules + .each(function() { + var + settings = ( $.isPlainObject(parameters) ) + ? $.extend(true, {}, $.fn.accordion.settings, parameters) + : $.extend({}, $.fn.accordion.settings), + + className = settings.className, + namespace = settings.namespace, + selector = settings.selector, + error = settings.error, + + eventNamespace = '.' + namespace, + moduleNamespace = 'module-' + namespace, + moduleSelector = $allModules.selector || '', + + $module = $(this), + $title = $module.find(selector.title), + $content = $module.find(selector.content), + + element = this, + instance = $module.data(moduleNamespace), + observer, + module + ; + + module = { + + initialize: function() { + module.debug('Initializing', $module); + module.bind.events(); + if(settings.observeChanges) { + module.observeChanges(); + } + module.instantiate(); + }, + + instantiate: function() { + instance = module; + $module + .data(moduleNamespace, module) + ; + }, + + destroy: function() { + module.debug('Destroying previous instance', $module); + $module + .off(eventNamespace) + .removeData(moduleNamespace) + ; + }, + + refresh: function() { + $title = $module.find(selector.title); + $content = $module.find(selector.content); + }, + + observeChanges: function() { + if('MutationObserver' in window) { + observer = new MutationObserver(function(mutations) { + module.debug('DOM tree modified, updating selector cache'); + module.refresh(); + }); + observer.observe(element, { + childList : true, + subtree : true + }); + module.debug('Setting up mutation observer', observer); + } + }, + + bind: { + events: function() { + module.debug('Binding delegated events'); + $module + .on(settings.on + eventNamespace, selector.trigger, module.event.click) + ; + } + }, + + event: { + click: function() { + module.toggle.call(this); + } + }, + + toggle: function(query) { + var + $activeTitle = (query !== undefined) + ? (typeof query === 'number') + ? $title.eq(query) + : $(query).closest(selector.title) + : $(this).closest(selector.title), + $activeContent = $activeTitle.next($content), + isAnimating = $activeContent.hasClass(className.animating), + isActive = $activeContent.hasClass(className.active), + isOpen = (isActive && !isAnimating), + isOpening = (!isActive && isAnimating) + ; + module.debug('Toggling visibility of content', $activeTitle); + if(isOpen || isOpening) { + if(settings.collapsible) { + module.close.call($activeTitle); + } + else { + module.debug('Cannot close accordion content collapsing is disabled'); + } + } + else { + module.open.call($activeTitle); + } + }, + + open: function(query) { + var + $activeTitle = (query !== undefined) + ? (typeof query === 'number') + ? $title.eq(query) + : $(query).closest(selector.title) + : $(this).closest(selector.title), + $activeContent = $activeTitle.next($content), + isAnimating = $activeContent.hasClass(className.animating), + isActive = $activeContent.hasClass(className.active), + isOpen = (isActive || isAnimating) + ; + if(isOpen) { + module.debug('Accordion already open, skipping', $activeContent); + return; + } + module.debug('Opening accordion content', $activeTitle); + settings.onOpening.call($activeContent); + settings.onChanging.call($activeContent); + if(settings.exclusive) { + module.closeOthers.call($activeTitle); + } + $activeTitle + .addClass(className.active) + ; + $activeContent + .stop(true, true) + .addClass(className.animating) + ; + if(settings.animateChildren) { + if($.fn.transition !== undefined && $module.transition('is supported')) { + $activeContent + .children() + .transition({ + animation : 'fade in', + queue : false, + useFailSafe : true, + debug : settings.debug, + verbose : settings.verbose, + duration : settings.duration, + skipInlineHidden : true, + onComplete: function() { + $activeContent.children().removeClass(className.transition); + } + }) + ; + } + else { + $activeContent + .children() + .stop(true, true) + .animate({ + opacity: 1 + }, settings.duration, module.resetOpacity) + ; + } + } + $activeContent + .slideDown(settings.duration, settings.easing, function() { + $activeContent + .removeClass(className.animating) + .addClass(className.active) + ; + module.reset.display.call(this); + settings.onOpen.call(this); + settings.onChange.call(this); + }) + ; + }, + + close: function(query) { + var + $activeTitle = (query !== undefined) + ? (typeof query === 'number') + ? $title.eq(query) + : $(query).closest(selector.title) + : $(this).closest(selector.title), + $activeContent = $activeTitle.next($content), + isAnimating = $activeContent.hasClass(className.animating), + isActive = $activeContent.hasClass(className.active), + isOpening = (!isActive && isAnimating), + isClosing = (isActive && isAnimating) + ; + if((isActive || isOpening) && !isClosing) { + module.debug('Closing accordion content', $activeContent); + settings.onClosing.call($activeContent); + settings.onChanging.call($activeContent); + $activeTitle + .removeClass(className.active) + ; + $activeContent + .stop(true, true) + .addClass(className.animating) + ; + if(settings.animateChildren) { + if($.fn.transition !== undefined && $module.transition('is supported')) { + $activeContent + .children() + .transition({ + animation : 'fade out', + queue : false, + useFailSafe : true, + debug : settings.debug, + verbose : settings.verbose, + duration : settings.duration, + skipInlineHidden : true + }) + ; + } + else { + $activeContent + .children() + .stop(true, true) + .animate({ + opacity: 0 + }, settings.duration, module.resetOpacity) + ; + } + } + $activeContent + .slideUp(settings.duration, settings.easing, function() { + $activeContent + .removeClass(className.animating) + .removeClass(className.active) + ; + module.reset.display.call(this); + settings.onClose.call(this); + settings.onChange.call(this); + }) + ; + } + }, + + closeOthers: function(index) { + var + $activeTitle = (index !== undefined) + ? $title.eq(index) + : $(this).closest(selector.title), + $parentTitles = $activeTitle.parents(selector.content).prev(selector.title), + $activeAccordion = $activeTitle.closest(selector.accordion), + activeSelector = selector.title + '.' + className.active + ':visible', + activeContent = selector.content + '.' + className.active + ':visible', + $openTitles, + $nestedTitles, + $openContents + ; + if(settings.closeNested) { + $openTitles = $activeAccordion.find(activeSelector).not($parentTitles); + $openContents = $openTitles.next($content); + } + else { + $openTitles = $activeAccordion.find(activeSelector).not($parentTitles); + $nestedTitles = $activeAccordion.find(activeContent).find(activeSelector).not($parentTitles); + $openTitles = $openTitles.not($nestedTitles); + $openContents = $openTitles.next($content); + } + if( ($openTitles.length > 0) ) { + module.debug('Exclusive enabled, closing other content', $openTitles); + $openTitles + .removeClass(className.active) + ; + $openContents + .removeClass(className.animating) + .stop(true, true) + ; + if(settings.animateChildren) { + if($.fn.transition !== undefined && $module.transition('is supported')) { + $openContents + .children() + .transition({ + animation : 'fade out', + useFailSafe : true, + debug : settings.debug, + verbose : settings.verbose, + duration : settings.duration, + skipInlineHidden : true + }) + ; + } + else { + $openContents + .children() + .stop(true, true) + .animate({ + opacity: 0 + }, settings.duration, module.resetOpacity) + ; + } + } + $openContents + .slideUp(settings.duration , settings.easing, function() { + $(this).removeClass(className.active); + module.reset.display.call(this); + }) + ; + } + }, + + reset: { + + display: function() { + module.verbose('Removing inline display from element', this); + $(this).css('display', ''); + if( $(this).attr('style') === '') { + $(this) + .attr('style', '') + .removeAttr('style') + ; + } + }, + + opacity: function() { + module.verbose('Removing inline opacity from element', this); + $(this).css('opacity', ''); + if( $(this).attr('style') === '') { + $(this) + .attr('style', '') + .removeAttr('style') + ; + } + }, + + }, + + 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) { + module.debug('Changing internal', name, value); + if(value !== undefined) { + if( $.isPlainObject(name) ) { + $.extend(true, module, name); + } + else { + 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(Array.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.accordion.settings = { + + name : 'Accordion', + namespace : 'accordion', + + silent : false, + debug : false, + verbose : false, + performance : true, + + on : 'click', // event on title that opens accordion + + observeChanges : true, // whether accordion should automatically refresh on DOM insertion + + exclusive : true, // whether a single accordion content panel should be open at once + collapsible : true, // whether accordion content can be closed + closeNested : false, // whether nested content should be closed when a panel is closed + animateChildren : true, // whether children opacity should be animated + + duration : 350, // duration of animation + easing : 'easeOutQuad', // easing equation for animation + + onOpening : function(){}, // callback before open animation + onClosing : function(){}, // callback before closing animation + onChanging : function(){}, // callback before closing or opening animation + + onOpen : function(){}, // callback after open animation + onClose : function(){}, // callback after closing animation + onChange : function(){}, // callback after closing or opening animation + + error: { + method : 'The method you called is not defined' + }, + + className : { + active : 'active', + animating : 'animating', + transition: 'transition' + }, + + selector : { + accordion : '.accordion', + title : '.title', + trigger : '.title', + content : '.content' + } + +}; + +// Adds easing +$.extend( $.easing, { + easeOutQuad: function (x, t, b, c, d) { + return -c *(t/=d)*(t-2) + b; + } +}); + +})( jQuery, window, document ); + diff --git a/semantic/src/definitions/modules/accordion.less b/semantic/src/definitions/modules/accordion.less new file mode 100644 index 0000000..7fe052f --- /dev/null +++ b/semantic/src/definitions/modules/accordion.less @@ -0,0 +1,219 @@ +/*! + * # Fomantic-UI - Accordion + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +/******************************* + Theme +*******************************/ + +@type : 'module'; +@element : 'accordion'; + +@import (multiple) '../../theme.config'; + +/******************************* + Accordion +*******************************/ + +.ui.accordion, +.ui.accordion .accordion { + max-width: 100%; +} +.ui.accordion .accordion { + margin: @childAccordionMargin; + padding: @childAccordionPadding; +} + +/* Title */ +.ui.accordion .title, +.ui.accordion .accordion .title { + cursor: pointer; +} + +/* Default Styling */ +.ui.accordion .title:not(.ui) { + padding: @titlePadding; + font-family: @titleFont; + font-size: @titleFontSize; + color: @titleColor; +} + +/* Default Styling */ +.ui.accordion:not(.styled) .title ~ .content:not(.ui), +.ui.accordion:not(.styled) .accordion .title ~ .content:not(.ui) { + margin: @contentMargin; + padding: @contentPadding; +} +.ui.accordion:not(.styled) .title ~ .content:not(.ui):last-child { + padding-bottom: 0; +} + +/* Arrow */ +.ui.accordion .title .dropdown.icon, +.ui.accordion .accordion .title .dropdown.icon { + display: @iconDisplay; + float: @iconFloat; + opacity: @iconOpacity; + width: @iconWidth; + height: @iconHeight; + margin: @iconMargin; + padding: @iconPadding; + font-size: @iconFontSize; + transition: @iconTransition; + vertical-align: @iconVerticalAlign; + transform: @iconTransform; +} + +/*-------------- + Coupling +---------------*/ + +/* Menu */ +.ui.accordion.menu .item .title { + display: block; + padding: @menuTitlePadding; +} +.ui.accordion.menu .item .title > .dropdown.icon { + float: @menuIconFloat; + margin: @menuIconMargin; + transform: @menuIconTransform; +} + +/* Header */ +.ui.accordion .ui.header .dropdown.icon { + font-size: @iconFontSize; + margin: @iconMargin; +} + +/******************************* + States +*******************************/ + +.ui.accordion .active.title .dropdown.icon, +.ui.accordion .accordion .active.title .dropdown.icon { + transform: @activeIconTransform; +} + +.ui.accordion.menu .item .active.title > .dropdown.icon { + transform: @activeIconTransform; +} + +/******************************* + Types +*******************************/ + +& when (@variationAccordionStyled) { + /*-------------- + Styled + ---------------*/ + + .ui.styled.accordion { + width: @styledWidth; + } + + .ui.styled.accordion, + .ui.styled.accordion .accordion { + border-radius: @styledBorderRadius; + background: @styledBackground; + box-shadow: @styledBoxShadow; + } + .ui.styled.accordion .title, + .ui.styled.accordion .accordion .title { + margin: @styledTitleMargin; + padding: @styledTitlePadding; + color: @styledTitleColor; + font-weight: @styledTitleFontWeight; + border-top: @styledTitleBorder; + transition: @styledTitleTransition; + } + .ui.styled.accordion > .title:first-child, + .ui.styled.accordion .accordion .title:first-child { + border-top: none; + } + + + /* Content */ + .ui.styled.accordion .content, + .ui.styled.accordion .accordion .content { + margin: @styledContentMargin; + padding: @styledContentPadding; + } + .ui.styled.accordion .accordion .content { + margin: @styledChildContentMargin; + padding: @styledChildContentPadding; + } + + + /* Hover */ + .ui.styled.accordion .title:hover, + .ui.styled.accordion .active.title, + .ui.styled.accordion .accordion .title:hover, + .ui.styled.accordion .accordion .active.title { + background: @styledTitleHoverBackground; + color: @styledTitleHoverColor; + } + .ui.styled.accordion .accordion .title:hover, + .ui.styled.accordion .accordion .active.title { + background: @styledHoverChildTitleBackground; + color: @styledHoverChildTitleColor; + } + + + /* Active */ + .ui.styled.accordion .active.title { + background: @styledActiveTitleBackground; + color: @styledActiveTitleColor; + } + .ui.styled.accordion .accordion .active.title { + background: @styledActiveChildTitleBackground; + color: @styledActiveChildTitleColor; + } +} + + +/******************************* + States +*******************************/ + +/*-------------- + Not Active +---------------*/ + +.ui.accordion .title ~ .content:not(.active), +.ui.accordion .accordion .title ~ .content:not(.active) { + display: none; +} + +/******************************* + Variations +*******************************/ + +& when (@variationAccordionFluid) { + /*-------------- + Fluid + ---------------*/ + + .ui.fluid.accordion, + .ui.fluid.accordion .accordion { + width: 100%; + } +} + +& when (@variationAccordionInverted) { + /*-------------- + Inverted + ---------------*/ + + .ui.inverted.accordion .title:not(.ui) { + color: @invertedTitleColor; + } +} + +.loadUIOverrides(); + diff --git a/semantic/src/definitions/modules/calendar.js b/semantic/src/definitions/modules/calendar.js new file mode 100644 index 0000000..1757f32 --- /dev/null +++ b/semantic/src/definitions/modules/calendar.js @@ -0,0 +1,1774 @@ +/*! + * # Fomantic-UI - Calendar + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +'use strict'; + +$.isFunction = $.isFunction || function(obj) { + return typeof obj === "function" && typeof obj.nodeType !== "number"; +}; + +window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.fn.calendar = 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), + returnedValue, + timeGapTable = { + '5': {'row': 4, 'column': 3 }, + '10': {'row': 3, 'column': 2 }, + '15': {'row': 2, 'column': 2 }, + '20': {'row': 3, 'column': 1 }, + '30': {'row': 2, 'column': 1 } + }, + numberText = ['','one','two','three','four','five','six','seven','eight'] + ; + + $allModules + .each(function () { + var + settings = ( $.isPlainObject(parameters) ) + ? $.extend(true, {}, $.fn.calendar.settings, parameters) + : $.extend({}, $.fn.calendar.settings), + + className = settings.className, + namespace = settings.namespace, + selector = settings.selector, + formatter = settings.formatter, + parser = settings.parser, + metadata = settings.metadata, + timeGap = timeGapTable[settings.minTimeGap], + error = settings.error, + + eventNamespace = '.' + namespace, + moduleNamespace = 'module-' + namespace, + + $module = $(this), + $input = $module.find(selector.input), + $container = $module.find(selector.popup), + $activator = $module.find(selector.activator), + + element = this, + instance = $module.data(moduleNamespace), + + isTouch, + isTouchDown = false, + isInverted = $module.hasClass(className.inverted), + focusDateUsedForRange = false, + selectionComplete = false, + classObserver, + module + ; + + module = { + + initialize: function () { + module.debug('Initializing calendar for', element, $module); + + isTouch = module.get.isTouch(); + module.setup.config(); + module.setup.popup(); + module.setup.inline(); + module.setup.input(); + module.setup.date(); + module.create.calendar(); + + module.bind.events(); + module.observeChanges(); + module.instantiate(); + }, + + instantiate: function () { + module.verbose('Storing instance of calendar'); + instance = module; + $module.data(moduleNamespace, instance); + }, + + destroy: function () { + module.verbose('Destroying previous calendar for', element); + $module.removeData(moduleNamespace); + module.unbind.events(); + module.disconnect.classObserver(); + }, + + setup: { + config: function () { + if (module.get.minDate() !== null) { + module.set.minDate($module.data(metadata.minDate)); + } + if (module.get.maxDate() !== null) { + module.set.maxDate($module.data(metadata.maxDate)); + } + module.setting('type', module.get.type()); + module.setting('on', settings.on || ($input.length ? 'focus' : 'click')); + }, + popup: function () { + if (settings.inline) { + return; + } + if (!$activator.length) { + $activator = $module.children().first(); + if (!$activator.length) { + return; + } + } + if ($.fn.popup === undefined) { + module.error(error.popup); + return; + } + if (!$container.length) { + //prepend the popup element to the activator's parent so that it has less chance of messing with + //the styling (eg input action button needs to be the last child to have correct border radius) + var $activatorParent = $activator.parent(), + domPositionFunction = $activatorParent.closest(selector.append).length !== 0 ? 'appendTo' : 'prependTo'; + $container = $('<div/>').addClass(className.popup)[domPositionFunction]($activatorParent); + } + $container.addClass(className.calendar); + if(isInverted){ + $container.addClass(className.inverted); + } + var onVisible = function () { + module.refreshTooltips(); + return settings.onVisible.apply($container, arguments); + }; + var onHidden = settings.onHidden; + if (!$input.length) { + //no input, $container has to handle focus/blur + $container.attr('tabindex', '0'); + onVisible = function () { + module.refreshTooltips(); + module.focus(); + return settings.onVisible.apply($container, arguments); + }; + onHidden = function () { + module.blur(); + return settings.onHidden.apply($container, arguments); + }; + } + var onShow = function () { + //reset the focus date onShow + module.set.focusDate(module.get.date()); + module.set.mode(module.get.validatedMode(settings.startMode)); + return settings.onShow.apply($container, arguments); + }; + var on = module.setting('on'); + var options = $.extend({}, settings.popupOptions, { + popup: $container, + on: on, + hoverable: on === 'hover', + closable: on === 'click', + onShow: onShow, + onVisible: onVisible, + onHide: settings.onHide, + onHidden: onHidden + }); + module.popup(options); + }, + inline: function () { + if ($activator.length && !settings.inline) { + return; + } + settings.inline = true; + $container = $('<div/>').addClass(className.calendar).appendTo($module); + if (!$input.length) { + $container.attr('tabindex', '0'); + } + }, + input: function () { + if (settings.touchReadonly && $input.length && isTouch) { + $input.prop('readonly', true); + } + module.check.disabled(); + }, + date: function () { + var date; + if (settings.initialDate) { + date = parser.date(settings.initialDate, settings); + } else if ($module.data(metadata.date) !== undefined) { + date = parser.date($module.data(metadata.date), settings); + } else if ($input.length) { + date = parser.date($input.val(), settings); + } + module.set.date(date, settings.formatInput, false); + module.set.mode(module.get.mode(), false); + } + }, + + trigger: { + change: function() { + var + inputElement = $input[0] + ; + if(inputElement) { + var events = document.createEvent('HTMLEvents'); + module.verbose('Triggering native change event'); + events.initEvent('change', true, false); + inputElement.dispatchEvent(events); + } + } + }, + + create: { + calendar: function () { + var i, r, c, p, row, cell, pageGrid; + + var + mode = module.get.mode(), + today = new Date(), + date = module.get.date(), + focusDate = module.get.focusDate(), + display = module.helper.dateInRange(focusDate || date || settings.initialDate || today) + ; + + if (!focusDate) { + focusDate = display; + module.set.focusDate(focusDate, false, false); + } + + var + isYear = mode === 'year', + isMonth = mode === 'month', + isDay = mode === 'day', + isHour = mode === 'hour', + isMinute = mode === 'minute', + isTimeOnly = settings.type === 'time' + ; + + var multiMonth = Math.max(settings.multiMonth, 1); + var monthOffset = !isDay ? 0 : module.get.monthOffset(); + + var + minute = display.getMinutes(), + hour = display.getHours(), + day = display.getDate(), + startMonth = display.getMonth() + monthOffset, + year = display.getFullYear() + ; + + var columns = isDay ? settings.showWeekNumbers ? 8 : 7 : isHour ? 4 : timeGap['column']; + var rows = isDay || isHour ? 6 : timeGap['row']; + var pages = isDay ? multiMonth : 1; + + var container = $container; + var tooltipPosition = container.hasClass("left") ? "right center" : "left center"; + container.empty(); + if (pages > 1) { + pageGrid = $('<div/>').addClass(className.grid).appendTo(container); + } + + for (p = 0; p < pages; p++) { + if (pages > 1) { + var pageColumn = $('<div/>').addClass(className.column).appendTo(pageGrid); + container = pageColumn; + } + + var month = startMonth + p; + var firstMonthDayColumn = (new Date(year, month, 1).getDay() - settings.firstDayOfWeek % 7 + 7) % 7; + if (!settings.constantHeight && isDay) { + var requiredCells = new Date(year, month + 1, 0).getDate() + firstMonthDayColumn; + rows = Math.ceil(requiredCells / 7); + } + + var + yearChange = isYear ? 10 : isMonth ? 1 : 0, + monthChange = isDay ? 1 : 0, + dayChange = isHour || isMinute ? 1 : 0, + prevNextDay = isHour || isMinute ? day : 1, + prevDate = new Date(year - yearChange, month - monthChange, prevNextDay - dayChange, hour), + nextDate = new Date(year + yearChange, month + monthChange, prevNextDay + dayChange, hour), + prevLast = isYear ? new Date(Math.ceil(year / 10) * 10 - 9, 0, 0) : + isMonth ? new Date(year, 0, 0) : isDay ? new Date(year, month, 0) : new Date(year, month, day, -1), + nextFirst = isYear ? new Date(Math.ceil(year / 10) * 10 + 1, 0, 1) : + isMonth ? new Date(year + 1, 0, 1) : isDay ? new Date(year, month + 1, 1) : new Date(year, month, day + 1) + ; + + var tempMode = mode; + if (isDay && settings.showWeekNumbers){ + tempMode += ' andweek'; + } + var table = $('<table/>').addClass(className.table).addClass(tempMode).addClass(numberText[columns] + ' column').appendTo(container); + if(isInverted){ + table.addClass(className.inverted); + } + var textColumns = columns; + //no header for time-only mode + if (!isTimeOnly) { + var thead = $('<thead/>').appendTo(table); + + row = $('<tr/>').appendTo(thead); + cell = $('<th/>').attr('colspan', '' + columns).appendTo(row); + + var headerDate = isYear || isMonth ? new Date(year, 0, 1) : + isDay ? new Date(year, month, 1) : new Date(year, month, day, hour, minute); + var headerText = $('<span/>').addClass(className.link).appendTo(cell); + headerText.text(formatter.header(headerDate, mode, settings)); + var newMode = isMonth ? (settings.disableYear ? 'day' : 'year') : + isDay ? (settings.disableMonth ? 'year' : 'month') : 'day'; + headerText.data(metadata.mode, newMode); + + if (p === 0) { + var prev = $('<span/>').addClass(className.prev).appendTo(cell); + prev.data(metadata.focusDate, prevDate); + prev.toggleClass(className.disabledCell, !module.helper.isDateInRange(prevLast, mode)); + $('<i/>').addClass(className.prevIcon).appendTo(prev); + } + + if (p === pages - 1) { + var next = $('<span/>').addClass(className.next).appendTo(cell); + next.data(metadata.focusDate, nextDate); + next.toggleClass(className.disabledCell, !module.helper.isDateInRange(nextFirst, mode)); + $('<i/>').addClass(className.nextIcon).appendTo(next); + } + if (isDay) { + row = $('<tr/>').appendTo(thead); + if(settings.showWeekNumbers) { + cell = $('<th/>').appendTo(row); + cell.text(settings.text.weekNo); + cell.addClass(className.weekCell); + textColumns--; + } + for (i = 0; i < textColumns; i++) { + cell = $('<th/>').appendTo(row); + cell.text(formatter.dayColumnHeader((i + settings.firstDayOfWeek) % 7, settings)); + } + } + } + + var tbody = $('<tbody/>').appendTo(table); + i = isYear ? Math.ceil(year / 10) * 10 - 9 : isDay ? 1 - firstMonthDayColumn : 0; + for (r = 0; r < rows; r++) { + row = $('<tr/>').appendTo(tbody); + if(isDay && settings.showWeekNumbers){ + cell = $('<th/>').appendTo(row); + cell.text(module.get.weekOfYear(year,month,i+1-settings.firstDayOfWeek)); + cell.addClass(className.weekCell); + } + for (c = 0; c < textColumns; c++, i++) { + var cellDate = isYear ? new Date(i, month, 1, hour, minute) : + isMonth ? new Date(year, i, 1, hour, minute) : isDay ? new Date(year, month, i, hour, minute) : + isHour ? new Date(year, month, day, i) : new Date(year, month, day, hour, i * settings.minTimeGap); + var cellText = isYear ? i : + isMonth ? settings.text.monthsShort[i] : isDay ? cellDate.getDate() : + formatter.time(cellDate, settings, true); + cell = $('<td/>').addClass(className.cell).appendTo(row); + cell.text(cellText); + cell.data(metadata.date, cellDate); + var adjacent = isDay && cellDate.getMonth() !== ((month + 12) % 12); + var disabled = (!settings.selectAdjacentDays && adjacent) || !module.helper.isDateInRange(cellDate, mode) || settings.isDisabled(cellDate, mode) || module.helper.isDisabled(cellDate, mode) || !module.helper.isEnabled(cellDate, mode); + if (disabled) { + var disabledDate = module.helper.findDayAsObject(cellDate, mode, settings.disabledDates); + if (disabledDate !== null && disabledDate[metadata.message]) { + cell.attr("data-tooltip", disabledDate[metadata.message]); + cell.attr("data-position", disabledDate[metadata.position] || tooltipPosition); + if(disabledDate[metadata.inverted] || (isInverted && disabledDate[metadata.inverted] === undefined)) { + cell.attr("data-inverted", ''); + } + if(disabledDate[metadata.variation]) { + cell.attr("data-variation", disabledDate[metadata.variation]); + } + } + } else { + var eventDate = module.helper.findDayAsObject(cellDate, mode, settings.eventDates); + if (eventDate !== null) { + cell.addClass(eventDate[metadata.class] || settings.eventClass); + if (eventDate[metadata.message]) { + cell.attr("data-tooltip", eventDate[metadata.message]); + cell.attr("data-position", eventDate[metadata.position] || tooltipPosition); + if(eventDate[metadata.inverted] || (isInverted && eventDate[metadata.inverted] === undefined)) { + cell.attr("data-inverted", ''); + } + if(eventDate[metadata.variation]) { + cell.attr("data-variation", eventDate[metadata.variation]); + } + } + } + } + var active = module.helper.dateEqual(cellDate, date, mode); + var isToday = module.helper.dateEqual(cellDate, today, mode); + cell.toggleClass(className.adjacentCell, adjacent); + cell.toggleClass(className.disabledCell, disabled); + cell.toggleClass(className.activeCell, active && !adjacent); + if (!isHour && !isMinute) { + cell.toggleClass(className.todayCell, !adjacent && isToday); + } + + // Allow for external modifications of each cell + var cellOptions = { + mode: mode, + adjacent: adjacent, + disabled: disabled, + active: active, + today: isToday + }; + formatter.cell(cell, cellDate, cellOptions); + + if (module.helper.dateEqual(cellDate, focusDate, mode)) { + //ensure that the focus date is exactly equal to the cell date + //so that, if selected, the correct value is set + module.set.focusDate(cellDate, false, false); + } + } + } + + if (settings.today) { + var todayRow = $('<tr/>').appendTo(tbody); + var todayButton = $('<td/>').attr('colspan', '' + columns).addClass(className.today).appendTo(todayRow); + todayButton.text(formatter.today(settings)); + todayButton.data(metadata.date, today); + } + + module.update.focus(false, table); + + if(settings.inline){ + module.refreshTooltips(); + } + } + } + }, + + update: { + focus: function (updateRange, container) { + container = container || $container; + var mode = module.get.mode(); + var date = module.get.date(); + var focusDate = module.get.focusDate(); + var startDate = module.get.startDate(); + var endDate = module.get.endDate(); + var rangeDate = (updateRange ? focusDate : null) || date || (!isTouch ? focusDate : null); + + container.find('td').each(function () { + var cell = $(this); + var cellDate = cell.data(metadata.date); + if (!cellDate) { + return; + } + var disabled = cell.hasClass(className.disabledCell); + var active = cell.hasClass(className.activeCell); + var adjacent = cell.hasClass(className.adjacentCell); + var focused = module.helper.dateEqual(cellDate, focusDate, mode); + var inRange = !rangeDate ? false : + ((!!startDate && module.helper.isDateInRange(cellDate, mode, startDate, rangeDate)) || + (!!endDate && module.helper.isDateInRange(cellDate, mode, rangeDate, endDate))); + cell.toggleClass(className.focusCell, focused && (!isTouch || isTouchDown) && (!adjacent || (settings.selectAdjacentDays && adjacent)) && !disabled); + + if (module.helper.isTodayButton(cell)) { + return; + } + cell.toggleClass(className.rangeCell, inRange && !active && !disabled); + }); + } + }, + + refresh: function () { + module.create.calendar(); + }, + + refreshTooltips: function() { + var winWidth = $(window).width(); + $container.find('td[data-position]').each(function () { + var cell = $(this); + var tooltipWidth = window.getComputedStyle(cell[0], ':after').width.replace(/[^0-9\.]/g,''); + var tooltipPosition = cell.attr('data-position'); + // use a fallback width of 250 (calendar width) for IE/Edge (which return "auto") + var calcPosition = (winWidth - cell.width() - (parseInt(tooltipWidth,10) || 250)) > cell.offset().left ? 'right' : 'left'; + if(tooltipPosition.indexOf(calcPosition) === -1) { + cell.attr('data-position',tooltipPosition.replace(/(left|right)/,calcPosition)); + } + }); + }, + + bind: { + events: function () { + module.debug('Binding events'); + $container.on('mousedown' + eventNamespace, module.event.mousedown); + $container.on('touchstart' + eventNamespace, module.event.mousedown); + $container.on('mouseup' + eventNamespace, module.event.mouseup); + $container.on('touchend' + eventNamespace, module.event.mouseup); + $container.on('mouseover' + eventNamespace, module.event.mouseover); + if ($input.length) { + $input.on('input' + eventNamespace, module.event.inputChange); + $input.on('focus' + eventNamespace, module.event.inputFocus); + $input.on('blur' + eventNamespace, module.event.inputBlur); + $input.on('keydown' + eventNamespace, module.event.keydown); + } else { + $container.on('keydown' + eventNamespace, module.event.keydown); + } + } + }, + + unbind: { + events: function () { + module.debug('Unbinding events'); + $container.off(eventNamespace); + if ($input.length) { + $input.off(eventNamespace); + } + } + }, + + event: { + mouseover: function (event) { + var target = $(event.target); + var date = target.data(metadata.date); + var mousedown = event.buttons === 1; + if (date) { + module.set.focusDate(date, false, true, mousedown); + } + }, + mousedown: function (event) { + if ($input.length) { + //prevent the mousedown on the calendar causing the input to lose focus + event.preventDefault(); + } + isTouchDown = event.type.indexOf('touch') >= 0; + var target = $(event.target); + var date = target.data(metadata.date); + if (date) { + module.set.focusDate(date, false, true, true); + } + }, + mouseup: function (event) { + //ensure input has focus so that it receives keydown events for calendar navigation + module.focus(); + event.preventDefault(); + event.stopPropagation(); + isTouchDown = false; + var target = $(event.target); + if (target.hasClass("disabled")) { + return; + } + var parent = target.parent(); + if (parent.data(metadata.date) || parent.data(metadata.focusDate) || parent.data(metadata.mode)) { + //clicked on a child element, switch to parent (used when clicking directly on prev/next <i> icon element) + target = parent; + } + var date = target.data(metadata.date); + var focusDate = target.data(metadata.focusDate); + var mode = target.data(metadata.mode); + if (date && settings.onSelect.call(element, date, module.get.mode()) !== false) { + var forceSet = target.hasClass(className.today); + module.selectDate(date, forceSet); + } + else if (focusDate) { + module.set.focusDate(focusDate); + } + else if (mode) { + module.set.mode(mode); + } + }, + keydown: function (event) { + var keyCode = event.which; + if (keyCode === 27 || keyCode === 9) { + //esc || tab + module.popup('hide'); + } + + if (module.popup('is visible')) { + if (keyCode === 37 || keyCode === 38 || keyCode === 39 || keyCode === 40) { + //arrow keys + var mode = module.get.mode(); + var bigIncrement = mode === 'day' ? 7 : mode === 'hour' ? 4 : mode === 'minute' ? timeGap['column'] : 3; + var increment = keyCode === 37 ? -1 : keyCode === 38 ? -bigIncrement : keyCode == 39 ? 1 : bigIncrement; + increment *= mode === 'minute' ? settings.minTimeGap : 1; + var focusDate = module.get.focusDate() || module.get.date() || new Date(); + var year = focusDate.getFullYear() + (mode === 'year' ? increment : 0); + var month = focusDate.getMonth() + (mode === 'month' ? increment : 0); + var day = focusDate.getDate() + (mode === 'day' ? increment : 0); + var hour = focusDate.getHours() + (mode === 'hour' ? increment : 0); + var minute = focusDate.getMinutes() + (mode === 'minute' ? increment : 0); + var newFocusDate = new Date(year, month, day, hour, minute); + if (settings.type === 'time') { + newFocusDate = module.helper.mergeDateTime(focusDate, newFocusDate); + } + if (module.helper.isDateInRange(newFocusDate, mode)) { + module.set.focusDate(newFocusDate); + } + } else if (keyCode === 13) { + //enter + var mode = module.get.mode(); + var date = module.get.focusDate(); + if (date && !settings.isDisabled(date, mode) && !module.helper.isDisabled(date, mode) && module.helper.isEnabled(date, mode)) { + module.selectDate(date); + } + //disable form submission: + event.preventDefault(); + event.stopPropagation(); + } + } + + if (keyCode === 38 || keyCode === 40) { + //arrow-up || arrow-down + event.preventDefault(); //don't scroll + module.popup('show'); + } + }, + inputChange: function () { + var val = $input.val(); + var date = parser.date(val, settings); + module.set.date(date, false); + }, + inputFocus: function () { + $container.addClass(className.active); + }, + inputBlur: function () { + $container.removeClass(className.active); + if (settings.formatInput) { + var date = module.get.date(); + var text = formatter.datetime(date, settings); + $input.val(text); + } + if(selectionComplete){ + module.trigger.change(); + selectionComplete = false; + } + }, + class: { + mutation: function(mutations) { + mutations.forEach(function(mutation) { + if(mutation.attributeName === "class") { + module.check.disabled(); + } + }); + } + } + }, + + observeChanges: function() { + if('MutationObserver' in window) { + classObserver = new MutationObserver(module.event.class.mutation); + module.debug('Setting up mutation observer', classObserver); + module.observe.class(); + } + }, + + disconnect: { + classObserver: function() { + if($input.length && classObserver) { + classObserver.disconnect(); + } + } + }, + + observe: { + class: function() { + if($input.length && classObserver) { + classObserver.observe($module[0], { + attributes : true + }); + } + } + }, + + is: { + disabled: function() { + return $module.hasClass(className.disabled); + } + }, + + check: { + disabled: function(){ + $input.attr('tabindex',module.is.disabled() ? -1 : 0); + } + }, + + get: { + weekOfYear: function(weekYear,weekMonth,weekDay) { + // adapted from http://www.merlyn.demon.co.uk/weekcalc.htm + var ms1d = 864e5, // milliseconds in a day + ms7d = 7 * ms1d; // milliseconds in a week + + return function() { // return a closure so constants get calculated only once + var DC3 = Date.UTC(weekYear, weekMonth, weekDay + 3) / ms1d, // an Absolute Day Number + AWN = Math.floor(DC3 / 7), // an Absolute Week Number + Wyr = new Date(AWN * ms7d).getUTCFullYear(); + + return AWN - Math.floor(Date.UTC(Wyr, 0, 7) / ms7d) + 1; + }(); + }, + date: function () { + return module.helper.sanitiseDate($module.data(metadata.date)) || null; + }, + inputDate: function() { + return $input.val(); + }, + focusDate: function () { + return $module.data(metadata.focusDate) || null; + }, + startDate: function () { + var startModule = module.get.calendarModule(settings.startCalendar); + return (startModule ? startModule.get.date() : $module.data(metadata.startDate)) || null; + }, + endDate: function () { + var endModule = module.get.calendarModule(settings.endCalendar); + return (endModule ? endModule.get.date() : $module.data(metadata.endDate)) || null; + }, + minDate: function() { + return $module.data(metadata.minDate) || null; + }, + maxDate: function() { + return $module.data(metadata.maxDate) || null; + }, + monthOffset: function () { + return $module.data(metadata.monthOffset) || 0; + }, + mode: function () { + //only returns valid modes for the current settings + var mode = $module.data(metadata.mode) || settings.startMode; + return module.get.validatedMode(mode); + }, + validatedMode: function(mode){ + var validModes = module.get.validModes(); + if ($.inArray(mode, validModes) >= 0) { + return mode; + } + return settings.type === 'time' ? 'hour' : + settings.type === 'month' ? 'month' : + settings.type === 'year' ? 'year' : 'day'; + }, + type: function() { + return $module.data(metadata.type) || settings.type; + }, + validModes: function () { + var validModes = []; + if (settings.type !== 'time') { + if (!settings.disableYear || settings.type === 'year') { + validModes.push('year'); + } + if (!(settings.disableMonth || settings.type === 'year') || settings.type === 'month') { + validModes.push('month'); + } + if (settings.type.indexOf('date') >= 0) { + validModes.push('day'); + } + } + if (settings.type.indexOf('time') >= 0) { + validModes.push('hour'); + if (!settings.disableMinute) { + validModes.push('minute'); + } + } + return validModes; + }, + isTouch: function () { + try { + document.createEvent('TouchEvent'); + return true; + } + catch (e) { + return false; + } + }, + calendarModule: function (selector) { + if (!selector) { + return null; + } + if (!(selector instanceof $)) { + selector = $(selector).first(); + } + //assume range related calendars are using the same namespace + return selector.data(moduleNamespace); + } + }, + + set: { + date: function (date, updateInput, fireChange) { + updateInput = updateInput !== false; + fireChange = fireChange !== false; + date = module.helper.sanitiseDate(date); + date = module.helper.dateInRange(date); + + var mode = module.get.mode(); + var text = formatter.datetime(date, settings); + + if (fireChange && settings.onBeforeChange.call(element, date, text, mode) === false) { + return false; + } + + module.set.focusDate(date); + + if (settings.isDisabled(date, mode)) { + return false; + } + + var endDate = module.get.endDate(); + if (!!endDate && !!date && date > endDate) { + //selected date is greater than end date in range, so clear end date + module.set.endDate(undefined); + } + module.set.dataKeyValue(metadata.date, date); + + if (updateInput && $input.length) { + $input.val(text); + } + + if (fireChange) { + settings.onChange.call(element, date, text, mode); + } + }, + startDate: function (date, refreshCalendar) { + date = module.helper.sanitiseDate(date); + var startModule = module.get.calendarModule(settings.startCalendar); + if (startModule) { + startModule.set.date(date); + } + module.set.dataKeyValue(metadata.startDate, date, refreshCalendar); + }, + endDate: function (date, refreshCalendar) { + date = module.helper.sanitiseDate(date); + var endModule = module.get.calendarModule(settings.endCalendar); + if (endModule) { + endModule.set.date(date); + } + module.set.dataKeyValue(metadata.endDate, date, refreshCalendar); + }, + focusDate: function (date, refreshCalendar, updateFocus, updateRange) { + date = module.helper.sanitiseDate(date); + date = module.helper.dateInRange(date); + var isDay = module.get.mode() === 'day'; + var oldFocusDate = module.get.focusDate(); + if (isDay && date && oldFocusDate) { + var yearDelta = date.getFullYear() - oldFocusDate.getFullYear(); + var monthDelta = yearDelta * 12 + date.getMonth() - oldFocusDate.getMonth(); + if (monthDelta) { + var monthOffset = module.get.monthOffset() - monthDelta; + module.set.monthOffset(monthOffset, false); + } + } + var changed = module.set.dataKeyValue(metadata.focusDate, date, !!date && refreshCalendar); + updateFocus = (updateFocus !== false && changed && refreshCalendar === false) || focusDateUsedForRange != updateRange; + focusDateUsedForRange = updateRange; + if (updateFocus) { + module.update.focus(updateRange); + } + }, + minDate: function (date) { + date = module.helper.sanitiseDate(date); + if (settings.maxDate !== null && settings.maxDate <= date) { + module.verbose('Unable to set minDate variable bigger that maxDate variable', date, settings.maxDate); + } else { + module.setting('minDate', date); + module.set.dataKeyValue(metadata.minDate, date); + } + }, + maxDate: function (date) { + date = module.helper.sanitiseDate(date); + if (settings.minDate !== null && settings.minDate >= date) { + module.verbose('Unable to set maxDate variable lower that minDate variable', date, settings.minDate); + } else { + module.setting('maxDate', date); + module.set.dataKeyValue(metadata.maxDate, date); + } + }, + monthOffset: function (monthOffset, refreshCalendar) { + var multiMonth = Math.max(settings.multiMonth, 1); + monthOffset = Math.max(1 - multiMonth, Math.min(0, monthOffset)); + module.set.dataKeyValue(metadata.monthOffset, monthOffset, refreshCalendar); + }, + mode: function (mode, refreshCalendar) { + module.set.dataKeyValue(metadata.mode, mode, refreshCalendar); + }, + dataKeyValue: function (key, value, refreshCalendar) { + var oldValue = $module.data(key); + var equal = oldValue === value || (oldValue <= value && oldValue >= value); //equality test for dates and string objects + if (value) { + $module.data(key, value); + } else { + $module.removeData(key); + } + refreshCalendar = refreshCalendar !== false && !equal; + if (refreshCalendar) { + module.refresh(); + } + return !equal; + } + }, + + selectDate: function (date, forceSet) { + module.verbose('New date selection', date); + var mode = module.get.mode(); + var complete = forceSet || mode === 'minute' || + (settings.disableMinute && mode === 'hour') || + (settings.type === 'date' && mode === 'day') || + (settings.type === 'month' && mode === 'month') || + (settings.type === 'year' && mode === 'year'); + if (complete) { + var canceled = module.set.date(date) === false; + if (!canceled) { + selectionComplete = true; + if(settings.closable) { + module.popup('hide'); + //if this is a range calendar, focus the container or input. This will open the popup from its event listeners. + var endModule = module.get.calendarModule(settings.endCalendar); + if (endModule) { + if (endModule.setting('on') !== 'focus') { + endModule.popup('show'); + } + endModule.focus(); + } + } + } + } else { + var newMode = mode === 'year' ? (!settings.disableMonth ? 'month' : 'day') : + mode === 'month' ? 'day' : mode === 'day' ? 'hour' : 'minute'; + module.set.mode(newMode); + if (mode === 'hour' || (mode === 'day' && module.get.date())) { + //the user has chosen enough to consider a valid date/time has been chosen + module.set.date(date, true, false); + } else { + module.set.focusDate(date); + } + } + }, + + changeDate: function (date) { + module.set.date(date); + }, + + clear: function () { + module.set.date(undefined); + }, + + popup: function () { + return $activator.popup.apply($activator, arguments); + }, + + focus: function () { + if ($input.length) { + $input.focus(); + } else { + $container.focus(); + } + }, + blur: function () { + if ($input.length) { + $input.blur(); + } else { + $container.blur(); + } + }, + + helper: { + isDisabled: function(date, mode) { + return (mode === 'day' || mode === 'month' || mode === 'year') && ((settings.disabledDaysOfWeek.indexOf(date.getDay()) !== -1) || settings.disabledDates.some(function(d){ + if(typeof d === 'string') { + d = module.helper.sanitiseDate(d); + } + if (d instanceof Date) { + return module.helper.dateEqual(date, d, mode); + } + if (d !== null && typeof d === 'object') { + if (d[metadata.year]) { + if (typeof d[metadata.year] === 'number') { + return date.getFullYear() == d[metadata.year]; + } else if (Array.isArray(d[metadata.year])) { + return d[metadata.year].indexOf(date.getFullYear()) > -1; + } + } else if (d[metadata.month]) { + if (typeof d[metadata.month] === 'number') { + return date.getMonth() == d[metadata.month]; + } else if (Array.isArray(d[metadata.month])) { + return d[metadata.month].indexOf(date.getMonth()) > -1; + } else if (d[metadata.month] instanceof Date) { + var sdate = module.helper.sanitiseDate(d[metadata.month]); + return (date.getMonth() == sdate.getMonth()) && (date.getFullYear() == sdate.getFullYear()) + } + } else if (d[metadata.date] && mode === 'day') { + if (d[metadata.date] instanceof Date) { + return module.helper.dateEqual(date, module.helper.sanitiseDate(d[metadata.date]), mode); + } else if (Array.isArray(d[metadata.date])) { + return d[metadata.date].some(function(idate) { + return module.helper.dateEqual(date, idate, mode); + }); + } + } + } + })); + }, + isEnabled: function(date, mode) { + if (mode === 'day') { + return settings.enabledDates.length === 0 || settings.enabledDates.some(function(d){ + if(typeof d === 'string') { + d = module.helper.sanitiseDate(d); + } + if (d instanceof Date) { + return module.helper.dateEqual(date, d, mode); + } + if (d !== null && typeof d === 'object' && d[metadata.date]) { + return module.helper.dateEqual(date, module.helper.sanitiseDate(d[metadata.date]), mode); + } + }); + } else { + return true; + } + }, + findDayAsObject: function(date, mode, dates) { + if (mode === 'day' || mode === 'month' || mode === 'year') { + var d; + for (var i = 0; i < dates.length; i++) { + d = dates[i]; + if(typeof d === 'string') { + d = module.helper.sanitiseDate(d); + } + if (d instanceof Date && module.helper.dateEqual(date, d, mode)) { + var dateObject = {}; + dateObject[metadata.date] = d; + return dateObject; + } + else if (d !== null && typeof d === 'object') { + if (d[metadata.year]) { + if (typeof d[metadata.year] === 'number' && date.getFullYear() == d[metadata.year]) { + return d; + } else if (Array.isArray(d[metadata.year])) { + if (d[metadata.year].indexOf(date.getFullYear()) > -1) { + return d; + } + } + } else if (d[metadata.month]) { + if (typeof d[metadata.month] === 'number' && date.getMonth() == d[metadata.month]) { + return d; + } else if (Array.isArray(d[metadata.month])) { + if (d[metadata.month].indexOf(date.getMonth()) > -1) { + return d; + } + } else if (d[metadata.month] instanceof Date) { + var sdate = module.helper.sanitiseDate(d[metadata.month]); + if ((date.getMonth() == sdate.getMonth()) && (date.getFullYear() == sdate.getFullYear())) { + return d; + } + } + } else if (d[metadata.date] && mode === 'day') { + if (d[metadata.date] instanceof Date && module.helper.dateEqual(date, module.helper.sanitiseDate(d[metadata.date]), mode)) { + return d; + } else if (Array.isArray(d[metadata.date])) { + if(d[metadata.date].some(function(idate) { return module.helper.dateEqual(date, idate, mode); })) { + return d; + } + } + } + } + } + } + return null; + }, + sanitiseDate: function (date) { + if (!date) { + return undefined; + } + if (!(date instanceof Date)) { + date = parser.date('' + date, settings); + } + if (!date || date === null || isNaN(date.getTime())) { + return undefined; + } + return date; + }, + dateDiff: function (date1, date2, mode) { + mode = mode || 'day'; + var isTimeOnly = settings.type === 'time'; + var isYear = mode === 'year'; + var isYearOrMonth = isYear || mode === 'month'; + var isMinute = mode === 'minute'; + var isHourOrMinute = isMinute || mode === 'hour'; + //only care about a minute accuracy of settings.minTimeGap + date1 = new Date( + isTimeOnly ? 2000 : date1.getFullYear(), + isTimeOnly ? 0 : isYear ? 0 : date1.getMonth(), + isTimeOnly ? 1 : isYearOrMonth ? 1 : date1.getDate(), + !isHourOrMinute ? 0 : date1.getHours(), + !isMinute ? 0 : settings.minTimeGap * Math.floor(date1.getMinutes() / settings.minTimeGap)); + date2 = new Date( + isTimeOnly ? 2000 : date2.getFullYear(), + isTimeOnly ? 0 : isYear ? 0 : date2.getMonth(), + isTimeOnly ? 1 : isYearOrMonth ? 1 : date2.getDate(), + !isHourOrMinute ? 0 : date2.getHours(), + !isMinute ? 0 : settings.minTimeGap * Math.floor(date2.getMinutes() / settings.minTimeGap)); + return date2.getTime() - date1.getTime(); + }, + dateEqual: function (date1, date2, mode) { + return !!date1 && !!date2 && module.helper.dateDiff(date1, date2, mode) === 0; + }, + isDateInRange: function (date, mode, minDate, maxDate) { + if (!minDate && !maxDate) { + var startDate = module.get.startDate(); + minDate = startDate && settings.minDate ? new Date(Math.max(startDate, settings.minDate)) : startDate || settings.minDate; + maxDate = settings.maxDate; + } + minDate = minDate && new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate(), minDate.getHours(), settings.minTimeGap * Math.ceil(minDate.getMinutes() / settings.minTimeGap)); + return !(!date || + (minDate && module.helper.dateDiff(date, minDate, mode) > 0) || + (maxDate && module.helper.dateDiff(maxDate, date, mode) > 0)); + }, + dateInRange: function (date, minDate, maxDate) { + if (!minDate && !maxDate) { + var startDate = module.get.startDate(); + minDate = startDate && settings.minDate ? new Date(Math.max(startDate, settings.minDate)) : startDate || settings.minDate; + maxDate = settings.maxDate; + } + minDate = minDate && new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate(), minDate.getHours(), settings.minTimeGap * Math.ceil(minDate.getMinutes() / settings.minTimeGap)); + var isTimeOnly = settings.type === 'time'; + return !date ? date : + (minDate && module.helper.dateDiff(date, minDate, 'minute') > 0) ? + (isTimeOnly ? module.helper.mergeDateTime(date, minDate) : minDate) : + (maxDate && module.helper.dateDiff(maxDate, date, 'minute') > 0) ? + (isTimeOnly ? module.helper.mergeDateTime(date, maxDate) : maxDate) : + date; + }, + mergeDateTime: function (date, time) { + return (!date || !time) ? time : + new Date(date.getFullYear(), date.getMonth(), date.getDate(), time.getHours(), time.getMinutes()); + }, + isTodayButton: function(element) { + return element.text() === settings.text.today; + } + }, + + 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 (Array.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.calendar.settings = { + + name : 'Calendar', + namespace : 'calendar', + + silent: false, + debug: false, + verbose: false, + performance: false, + + type : 'datetime', // picker type, can be 'datetime', 'date', 'time', 'month', or 'year' + firstDayOfWeek : 0, // day for first day column (0 = Sunday) + constantHeight : true, // add rows to shorter months to keep day calendar height consistent (6 rows) + today : false, // show a 'today/now' button at the bottom of the calendar + closable : true, // close the popup after selecting a date/time + monthFirst : true, // month before day when parsing/converting date from/to text + touchReadonly : true, // set input to readonly on touch devices + inline : false, // create the calendar inline instead of inside a popup + on : null, // when to show the popup (defaults to 'focus' for input, 'click' for others) + initialDate : null, // date to display initially when no date is selected (null = now) + startMode : false, // display mode to start in, can be 'year', 'month', 'day', 'hour', 'minute' (false = 'day') + minDate : null, // minimum date/time that can be selected, dates/times before are disabled + maxDate : null, // maximum date/time that can be selected, dates/times after are disabled + ampm : true, // show am/pm in time mode + disableYear : false, // disable year selection mode + disableMonth : false, // disable month selection mode + disableMinute : false, // disable minute selection mode + formatInput : true, // format the input text upon input blur and module creation + startCalendar : null, // jquery object or selector for another calendar that represents the start date of a date range + endCalendar : null, // jquery object or selector for another calendar that represents the end date of a date range + multiMonth : 1, // show multiple months when in 'day' mode + minTimeGap : 5, + showWeekNumbers : null, // show Number of Week at the very first column of a dayView + disabledDates : [], // specific day(s) which won't be selectable and contain additional information. + disabledDaysOfWeek : [], // day(s) which won't be selectable(s) (0 = Sunday) + enabledDates : [], // specific day(s) which will be selectable, all other days will be disabled + eventDates : [], // specific day(s) which will be shown in a different color and using tooltips + centuryBreak : 60, // starting short year until 99 where it will be assumed to belong to the last century + currentCentury : 2000, // century to be added to 2-digit years (00 to {centuryBreak}-1) + selectAdjacentDays : false, // The calendar can show dates from adjacent month. These adjacent month dates can also be made selectable. + // popup options ('popup', 'on', 'hoverable', and show/hide callbacks are overridden) + popupOptions: { + position: 'bottom left', + lastResort: 'bottom left', + prefer: 'opposite', + hideOnScroll: false + }, + + text: { + days: ['S', 'M', 'T', 'W', 'T', 'F', 'S'], + months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], + monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + today: 'Today', + now: 'Now', + am: 'AM', + pm: 'PM', + weekNo: 'Week' + }, + + formatter: { + header: function (date, mode, settings) { + return mode === 'year' ? settings.formatter.yearHeader(date, settings) : + mode === 'month' ? settings.formatter.monthHeader(date, settings) : + mode === 'day' ? settings.formatter.dayHeader(date, settings) : + mode === 'hour' ? settings.formatter.hourHeader(date, settings) : + settings.formatter.minuteHeader(date, settings); + }, + yearHeader: function (date, settings) { + var decadeYear = Math.ceil(date.getFullYear() / 10) * 10; + return (decadeYear - 9) + ' - ' + (decadeYear + 2); + }, + monthHeader: function (date, settings) { + return date.getFullYear(); + }, + dayHeader: function (date, settings) { + var month = settings.text.months[date.getMonth()]; + var year = date.getFullYear(); + return month + ' ' + year; + }, + hourHeader: function (date, settings) { + return settings.formatter.date(date, settings); + }, + minuteHeader: function (date, settings) { + return settings.formatter.date(date, settings); + }, + dayColumnHeader: function (day, settings) { + return settings.text.days[day]; + }, + datetime: function (date, settings) { + if (!date) { + return ''; + } + var day = settings.type === 'time' ? '' : settings.formatter.date(date, settings); + var time = settings.type.indexOf('time') < 0 ? '' : settings.formatter.time(date, settings, false); + var separator = settings.type === 'datetime' ? ' ' : ''; + return day + separator + time; + }, + date: function (date, settings) { + if (!date) { + return ''; + } + var day = date.getDate(); + var month = settings.text.months[date.getMonth()]; + var year = date.getFullYear(); + return settings.type === 'year' ? year : + settings.type === 'month' ? month + ' ' + year : + (settings.monthFirst ? month + ' ' + day : day + ' ' + month) + ', ' + year; + }, + time: function (date, settings, forCalendar) { + if (!date) { + return ''; + } + var hour = date.getHours(); + var minute = date.getMinutes(); + var ampm = ''; + if (settings.ampm) { + ampm = ' ' + (hour < 12 ? settings.text.am : settings.text.pm); + hour = hour === 0 ? 12 : hour > 12 ? hour - 12 : hour; + } + return hour + ':' + (minute < 10 ? '0' : '') + minute + ampm; + }, + today: function (settings) { + return settings.type === 'date' ? settings.text.today : settings.text.now; + }, + cell: function (cell, date, cellOptions) { + } + }, + + parser: { + date: function (text, settings) { + if (text instanceof Date) { + return text; + } + if (!text) { + return null; + } + text = String(text).trim(); + if (text.length === 0) { + return null; + } + if(text.match(/^[0-9]{4}[\/\-\.][0-9]{2}[\/\-\.][0-9]{2}$/)){ + text = text.replace(/[\/\-\.]/g,'/') + ' 00:00:00'; + } + // Reverse date and month in some cases + text = settings.monthFirst || !text.match(/^[0-9]{2}[\/\-\.]/) ? text : text.replace(/[\/\-\.]/g,'/').replace(/([0-9]+)\/([0-9]+)/,'$2/$1'); + var textDate = new Date(text); + var numberOnly = text.match(/^[0-9]+$/) !== null; + if(!numberOnly && !isNaN(textDate.getDate())) { + return textDate; + } + text = text.toLowerCase(); + + var i, j, k; + var minute = -1, hour = -1, day = -1, month = -1, year = -1; + var isAm = undefined; + + var isTimeOnly = settings.type === 'time'; + var isDateOnly = settings.type.indexOf('time') < 0; + + var words = text.split(settings.regExp.dateWords), word; + var numbers = text.split(settings.regExp.dateNumbers), number; + + var parts; + var monthString; + + if (!isDateOnly) { + //am/pm + isAm = $.inArray(settings.text.am.toLowerCase(), words) >= 0 ? true : + $.inArray(settings.text.pm.toLowerCase(), words) >= 0 ? false : undefined; + + //time with ':' + for (i = 0; i < numbers.length; i++) { + number = numbers[i]; + if (number.indexOf(':') >= 0) { + if (hour < 0 || minute < 0) { + parts = number.split(':'); + for (k = 0; k < Math.min(2, parts.length); k++) { + j = parseInt(parts[k]); + if (isNaN(j)) { + j = 0; + } + if (k === 0) { + hour = j % 24; + } else { + minute = j % 60; + } + } + } + numbers.splice(i, 1); + } + } + } + + if (!isTimeOnly) { + //textual month + for (i = 0; i < words.length; i++) { + word = words[i]; + if (word.length <= 0) { + continue; + } + for (j = 0; j < settings.text.months.length; j++) { + monthString = settings.text.months[j]; + monthString = monthString.substring(0, word.length).toLowerCase(); + if (monthString === word) { + month = j + 1; + break; + } + } + if (month >= 0) { + break; + } + } + + //year > settings.centuryBreak + for (i = 0; i < numbers.length; i++) { + j = parseInt(numbers[i]); + if (isNaN(j)) { + continue; + } + if (j >= settings.centuryBreak && i === numbers.length-1) { + if (j <= 99) { + j += settings.currentCentury - 100; + } + year = j; + numbers.splice(i, 1); + break; + } + } + + //numeric month + if (month < 0) { + for (i = 0; i < numbers.length; i++) { + k = i > 1 || settings.monthFirst ? i : i === 1 ? 0 : 1; + j = parseInt(numbers[k]); + if (isNaN(j)) { + continue; + } + if (1 <= j && j <= 12) { + month = j; + numbers.splice(k, 1); + break; + } + } + } + + //day + for (i = 0; i < numbers.length; i++) { + j = parseInt(numbers[i]); + if (isNaN(j)) { + continue; + } + if (1 <= j && j <= 31) { + day = j; + numbers.splice(i, 1); + break; + } + } + + //year <= settings.centuryBreak + if (year < 0) { + for (i = numbers.length - 1; i >= 0; i--) { + j = parseInt(numbers[i]); + if (isNaN(j)) { + continue; + } + if (j <= 99) { + j += settings.currentCentury; + } + year = j; + numbers.splice(i, 1); + break; + } + } + } + + if (!isDateOnly) { + //hour + if (hour < 0) { + for (i = 0; i < numbers.length; i++) { + j = parseInt(numbers[i]); + if (isNaN(j)) { + continue; + } + if (0 <= j && j <= 23) { + hour = j; + numbers.splice(i, 1); + break; + } + } + } + + //minute + if (minute < 0) { + for (i = 0; i < numbers.length; i++) { + j = parseInt(numbers[i]); + if (isNaN(j)) { + continue; + } + if (0 <= j && j <= 59) { + minute = j; + numbers.splice(i, 1); + break; + } + } + } + } + + if (minute < 0 && hour < 0 && day < 0 && month < 0 && year < 0) { + return null; + } + + if (minute < 0) { + minute = 0; + } + if (hour < 0) { + hour = 0; + } + if (day < 0) { + day = 1; + } + if (month < 0) { + month = 1; + } + if (year < 0) { + year = new Date().getFullYear(); + } + + if (isAm !== undefined) { + if (isAm) { + if (hour === 12) { + hour = 0; + } + } else if (hour < 12) { + hour += 12; + } + } + + var date = new Date(year, month - 1, day, hour, minute); + if (date.getMonth() !== month - 1 || date.getFullYear() !== year) { + //month or year don't match up, switch to last day of the month + date = new Date(year, month, 0, hour, minute); + } + return isNaN(date.getTime()) ? null : date; + } + }, + + // callback before date is changed, return false to cancel the change + onBeforeChange: function (date, text, mode) { + return true; + }, + + // callback when date changes + onChange: function (date, text, mode) { + }, + + // callback before show animation, return false to prevent show + onShow: function () { + }, + + // callback after show animation + onVisible: function () { + }, + + // callback before hide animation, return false to prevent hide + onHide: function () { + }, + + // callback after hide animation + onHidden: function () { + }, + + // callback before item is selected, return false to prevent selection + onSelect: function (date, mode) { + }, + + // is the given date disabled? + isDisabled: function (date, mode) { + return false; + }, + + selector: { + popup: '.ui.popup', + input: 'input', + activator: 'input', + append: '.inline.field,.inline.fields' + }, + + regExp: { + dateWords: /[^A-Za-z\u00C0-\u024F]+/g, + dateNumbers: /[^\d:]+/g + }, + + error: { + popup: 'UI Popup, a required component is not included in this page', + method: 'The method you called is not defined.' + }, + + className: { + calendar: 'calendar', + active: 'active', + popup: 'ui popup', + grid: 'ui equal width grid', + column: 'column', + table: 'ui celled center aligned unstackable table', + inverted: 'inverted', + prev: 'prev link', + next: 'next link', + prevIcon: 'chevron left icon', + nextIcon: 'chevron right icon', + link: 'link', + cell: 'link', + disabledCell: 'disabled', + weekCell: 'disabled', + adjacentCell: 'adjacent', + activeCell: 'active', + rangeCell: 'range', + focusCell: 'focus', + todayCell: 'today', + today: 'today link', + disabled: 'disabled' + }, + + metadata: { + date: 'date', + focusDate: 'focusDate', + startDate: 'startDate', + endDate: 'endDate', + minDate: 'minDate', + maxDate: 'maxDate', + mode: 'mode', + type: 'type', + monthOffset: 'monthOffset', + message: 'message', + class: 'class', + inverted: 'inverted', + variation: 'variation', + position: 'position', + month: 'month', + year: 'year' + }, + + eventClass: 'blue' +}; + +})(jQuery, window, document); diff --git a/semantic/src/definitions/modules/calendar.less b/semantic/src/definitions/modules/calendar.less new file mode 100644 index 0000000..aaa7f11 --- /dev/null +++ b/semantic/src/definitions/modules/calendar.less @@ -0,0 +1,195 @@ +/*! + * # Fomantic-UI - Calendar + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +/******************************* + Theme +*******************************/ + +@type : 'module'; +@element : 'calendar'; + +@import (multiple) '../../theme.config'; + +/******************************* + Popup +*******************************/ + +.ui.calendar .ui.popup { + max-width: none; + padding: 0; + border: none; + user-select: none; +} + +/******************************* + Calendar +*******************************/ + +.ui.calendar .calendar:focus { + outline: 0; +} + +/******************************* + Grid +*******************************/ + +.ui.calendar .ui.popup .ui.grid { + display: block; + white-space: nowrap; +} + +.ui.calendar .ui.popup .ui.grid > .column { + width: auto; +} + +/******************************* + Table +*******************************/ + +.ui.calendar .ui.table.year, +.ui.calendar .ui.table.month, +.ui.calendar .ui.table.minute { + min-width: 15em; +} + +.ui.calendar .ui.table.day { + min-width: 18em; +} + +.ui.calendar .ui.table.day.andweek { + min-width: 22em; +} + +.ui.calendar .ui.table.hour { + min-width: 20em; +} + +.ui.calendar .ui.table tr th, +.ui.calendar .ui.table tr td { + padding: 0.5em; + white-space: nowrap; +} + +.ui.calendar .ui.table tr th { + border-left: none; +} + +.ui.calendar .ui.table tr th i.icon { + margin: 0; +} + +.ui.calendar .ui.table tr:first-child th { + position: relative; + padding-left: 0; + padding-right: 0; +} + +.ui.calendar .ui.table.day tr:first-child th { + border: none; +} + +.ui.calendar .ui.table.day tr:nth-child(2) th { + padding-top: 0.2em; + padding-bottom: 0.3em; +} + +.ui.calendar .ui.table tr td { + padding-left: 0.1em; + padding-right: 0.1em; +} + +.ui.calendar .ui.table tr .link { + cursor: pointer; +} + +.ui.calendar .ui.table tr .prev.link { + width: 14.28571429%; + position: absolute; + left: 0; +} + +.ui.calendar .ui.table tr .next.link { + width: 14.28571429%; + position: absolute; + right: 0; +} + +.ui.ui.calendar .ui.table tr .disabled { + pointer-events: auto; + cursor: default; + color: @disabledTextColor; +} + +.ui.calendar .ui.table tr .adjacent:not(.disabled) { + color: @adjacentTextColor; + background: @adjacentBackground; +} + +/*-------------- + States +---------------*/ + +.ui.calendar .ui.table tr td.today { + font-weight: @todayFontWeight; +} + +.ui.calendar .ui.table tr td.range { + background: @rangeBackground; + color: @rangeTextColor; + box-shadow: @rangeBoxShadow; +} + +.ui.calendar:not(.disabled) .calendar:focus .ui.table tbody tr td.focus, +.ui.calendar:not(.disabled) .calendar.active .ui.table tbody tr td.focus { + box-shadow: @focusBoxShadow; +} + +& when (@variationCalendarInverted) { + .ui.inverted.calendar .ui.table.inverted tr td.range { + background: @rangeInvertedBackground; + color: @rangeInvertedTextColor; + box-shadow: @rangeInvertedBoxShadow; + } + + .ui.inverted.calendar:not(.disabled) .calendar:focus .ui.table.inverted tbody tr td.focus, + .ui.inverted.calendar:not(.disabled) .calendar.active .ui.table.inverted tbody tr td.focus { + box-shadow: @focusInvertedBoxShadow; + } + .ui.inverted.calendar .ui.inverted.table tr .disabled { + color: @invertedDisabledTextColor; + } + + .ui.inverted.calendar .ui.inverted.table tr .adjacent:not(.disabled) { + color: @adjacentInvertedTextColor; + background: @adjacentInvertedBackground; + } +} + +/******************************* + States +*******************************/ + +& when (@variationCalendarDisabled) { + /*-------------------- + Disabled + ---------------------*/ + + .ui.disabled.calendar { + opacity: @disabledOpacity; + } + + .ui.disabled.calendar > .input, + .ui.disabled.calendar .ui.table tr .link { + pointer-events: none; + } +} + + +.loadUIOverrides(); diff --git a/semantic/src/definitions/modules/checkbox.js b/semantic/src/definitions/modules/checkbox.js new file mode 100644 index 0000000..c5540ba --- /dev/null +++ b/semantic/src/definitions/modules/checkbox.js @@ -0,0 +1,876 @@ +/*! + * # Fomantic-UI - Checkbox + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +'use strict'; + +$.isFunction = $.isFunction || function(obj) { + return typeof obj === "function" && typeof obj.nodeType !== "number"; +}; + +window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.fn.checkbox = 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), + returnedValue + ; + + $allModules + .each(function() { + var + settings = $.extend(true, {}, $.fn.checkbox.settings, parameters), + + className = settings.className, + namespace = settings.namespace, + selector = settings.selector, + error = settings.error, + + eventNamespace = '.' + namespace, + moduleNamespace = 'module-' + namespace, + + $module = $(this), + $label = $(this).children(selector.label), + $input = $(this).children(selector.input), + input = $input[0], + + initialLoad = false, + shortcutPressed = false, + instance = $module.data(moduleNamespace), + + observer, + element = this, + module + ; + + module = { + + initialize: function() { + module.verbose('Initializing checkbox', settings); + + module.create.label(); + module.bind.events(); + + module.set.tabbable(); + module.hide.input(); + + module.observeChanges(); + module.instantiate(); + module.setup(); + }, + + instantiate: function() { + module.verbose('Storing instance of module', module); + instance = module; + $module + .data(moduleNamespace, module) + ; + }, + + destroy: function() { + module.verbose('Destroying module'); + module.unbind.events(); + module.show.input(); + $module.removeData(moduleNamespace); + }, + + fix: { + reference: function() { + if( $module.is(selector.input) ) { + module.debug('Behavior called on <input> adjusting invoked element'); + $module = $module.closest(selector.checkbox); + module.refresh(); + } + } + }, + + setup: function() { + module.set.initialLoad(); + if( module.is.indeterminate() ) { + module.debug('Initial value is indeterminate'); + module.indeterminate(); + } + else if( module.is.checked() ) { + module.debug('Initial value is checked'); + module.check(); + } + else { + module.debug('Initial value is unchecked'); + module.uncheck(); + } + module.remove.initialLoad(); + }, + + refresh: function() { + $label = $module.children(selector.label); + $input = $module.children(selector.input); + input = $input[0]; + }, + + hide: { + input: function() { + module.verbose('Modifying <input> z-index to be unselectable'); + $input.addClass(className.hidden); + } + }, + show: { + input: function() { + module.verbose('Modifying <input> z-index to be selectable'); + $input.removeClass(className.hidden); + } + }, + + observeChanges: function() { + if('MutationObserver' in window) { + observer = new MutationObserver(function(mutations) { + module.debug('DOM tree modified, updating selector cache'); + module.refresh(); + }); + observer.observe(element, { + childList : true, + subtree : true + }); + module.debug('Setting up mutation observer', observer); + } + }, + + attachEvents: function(selector, event) { + var + $element = $(selector) + ; + event = $.isFunction(module[event]) + ? module[event] + : module.toggle + ; + if($element.length > 0) { + module.debug('Attaching checkbox events to element', selector, event); + $element + .on('click' + eventNamespace, event) + ; + } + else { + module.error(error.notFound); + } + }, + + preventDefaultOnInputTarget: function() { + if(typeof event !== 'undefined' && event !== null && $(event.target).is(selector.input)) { + module.verbose('Preventing default check action after manual check action'); + event.preventDefault(); + } + }, + + event: { + change: function(event) { + if( !module.should.ignoreCallbacks() ) { + settings.onChange.call(input); + } + }, + click: function(event) { + var + $target = $(event.target) + ; + if( $target.is(selector.input) ) { + module.verbose('Using default check action on initialized checkbox'); + return; + } + if( $target.is(selector.link) ) { + module.debug('Clicking link inside checkbox, skipping toggle'); + return; + } + module.toggle(); + $input.focus(); + event.preventDefault(); + }, + keydown: function(event) { + var + key = event.which, + keyCode = { + enter : 13, + space : 32, + escape : 27, + left : 37, + up : 38, + right : 39, + down : 40 + } + ; + + var r = module.get.radios(), + rIndex = r.index($module), + rLen = r.length, + checkIndex = false; + + if(key == keyCode.left || key == keyCode.up) { + checkIndex = (rIndex === 0 ? rLen : rIndex) - 1; + } else if(key == keyCode.right || key == keyCode.down) { + checkIndex = rIndex === rLen-1 ? 0 : rIndex+1; + } + + if (!module.should.ignoreCallbacks() && checkIndex !== false) { + if(settings.beforeUnchecked.apply(input)===false) { + module.verbose('Option not allowed to be unchecked, cancelling key navigation'); + return false; + } + if (settings.beforeChecked.apply($(r[checkIndex]).children(selector.input)[0])===false) { + module.verbose('Next option should not allow check, cancelling key navigation'); + return false; + } + } + + if(key == keyCode.escape) { + module.verbose('Escape key pressed blurring field'); + $input.blur(); + shortcutPressed = true; + } + else if(!event.ctrlKey && ( key == keyCode.space || (key == keyCode.enter && settings.enableEnterKey)) ) { + module.verbose('Enter/space key pressed, toggling checkbox'); + module.toggle(); + shortcutPressed = true; + } + else { + shortcutPressed = false; + } + }, + keyup: function(event) { + if(shortcutPressed) { + event.preventDefault(); + } + } + }, + + check: function() { + if( !module.should.allowCheck() ) { + return; + } + module.debug('Checking checkbox', $input); + module.set.checked(); + if( !module.should.ignoreCallbacks() ) { + settings.onChecked.call(input); + module.trigger.change(); + } + module.preventDefaultOnInputTarget(); + }, + + uncheck: function() { + if( !module.should.allowUncheck() ) { + return; + } + module.debug('Unchecking checkbox'); + module.set.unchecked(); + if( !module.should.ignoreCallbacks() ) { + settings.onUnchecked.call(input); + module.trigger.change(); + } + module.preventDefaultOnInputTarget(); + }, + + indeterminate: function() { + if( module.should.allowIndeterminate() ) { + module.debug('Checkbox is already indeterminate'); + return; + } + module.debug('Making checkbox indeterminate'); + module.set.indeterminate(); + if( !module.should.ignoreCallbacks() ) { + settings.onIndeterminate.call(input); + module.trigger.change(); + } + }, + + determinate: function() { + if( module.should.allowDeterminate() ) { + module.debug('Checkbox is already determinate'); + return; + } + module.debug('Making checkbox determinate'); + module.set.determinate(); + if( !module.should.ignoreCallbacks() ) { + settings.onDeterminate.call(input); + module.trigger.change(); + } + }, + + enable: function() { + if( module.is.enabled() ) { + module.debug('Checkbox is already enabled'); + return; + } + module.debug('Enabling checkbox'); + module.set.enabled(); + if( !module.should.ignoreCallbacks() ) { + settings.onEnable.call(input); + // preserve legacy callbacks + settings.onEnabled.call(input); + module.trigger.change(); + } + }, + + disable: function() { + if( module.is.disabled() ) { + module.debug('Checkbox is already disabled'); + return; + } + module.debug('Disabling checkbox'); + module.set.disabled(); + if( !module.should.ignoreCallbacks() ) { + settings.onDisable.call(input); + // preserve legacy callbacks + settings.onDisabled.call(input); + module.trigger.change(); + } + }, + + get: { + radios: function() { + var + name = module.get.name() + ; + return $('input[name="' + name + '"]').closest(selector.checkbox); + }, + otherRadios: function() { + return module.get.radios().not($module); + }, + name: function() { + return $input.attr('name'); + } + }, + + is: { + initialLoad: function() { + return initialLoad; + }, + radio: function() { + return ($input.hasClass(className.radio) || $input.attr('type') == 'radio'); + }, + indeterminate: function() { + return $input.prop('indeterminate') !== undefined && $input.prop('indeterminate'); + }, + checked: function() { + return $input.prop('checked') !== undefined && $input.prop('checked'); + }, + disabled: function() { + return $input.prop('disabled') !== undefined && $input.prop('disabled'); + }, + enabled: function() { + return !module.is.disabled(); + }, + determinate: function() { + return !module.is.indeterminate(); + }, + unchecked: function() { + return !module.is.checked(); + } + }, + + should: { + allowCheck: function() { + if(module.is.determinate() && module.is.checked() && !module.is.initialLoad() ) { + module.debug('Should not allow check, checkbox is already checked'); + return false; + } + if(!module.should.ignoreCallbacks() && settings.beforeChecked.apply(input) === false) { + module.debug('Should not allow check, beforeChecked cancelled'); + return false; + } + return true; + }, + allowUncheck: function() { + if(module.is.determinate() && module.is.unchecked() && !module.is.initialLoad() ) { + module.debug('Should not allow uncheck, checkbox is already unchecked'); + return false; + } + if(!module.should.ignoreCallbacks() && settings.beforeUnchecked.apply(input) === false) { + module.debug('Should not allow uncheck, beforeUnchecked cancelled'); + return false; + } + return true; + }, + allowIndeterminate: function() { + if(module.is.indeterminate() && !module.is.initialLoad() ) { + module.debug('Should not allow indeterminate, checkbox is already indeterminate'); + return false; + } + if(!module.should.ignoreCallbacks() && settings.beforeIndeterminate.apply(input) === false) { + module.debug('Should not allow indeterminate, beforeIndeterminate cancelled'); + return false; + } + return true; + }, + allowDeterminate: function() { + if(module.is.determinate() && !module.is.initialLoad() ) { + module.debug('Should not allow determinate, checkbox is already determinate'); + return false; + } + if(!module.should.ignoreCallbacks() && settings.beforeDeterminate.apply(input) === false) { + module.debug('Should not allow determinate, beforeDeterminate cancelled'); + return false; + } + return true; + }, + ignoreCallbacks: function() { + return (initialLoad && !settings.fireOnInit); + } + }, + + can: { + change: function() { + return !( $module.hasClass(className.disabled) || $module.hasClass(className.readOnly) || $input.prop('disabled') || $input.prop('readonly') ); + }, + uncheck: function() { + return (typeof settings.uncheckable === 'boolean') + ? settings.uncheckable + : !module.is.radio() + ; + } + }, + + set: { + initialLoad: function() { + initialLoad = true; + }, + checked: function() { + module.verbose('Setting class to checked'); + $module + .removeClass(className.indeterminate) + .addClass(className.checked) + ; + if( module.is.radio() ) { + module.uncheckOthers(); + } + if(!module.is.indeterminate() && module.is.checked()) { + module.debug('Input is already checked, skipping input property change'); + return; + } + module.verbose('Setting state to checked', input); + $input + .prop('indeterminate', false) + .prop('checked', true) + ; + }, + unchecked: function() { + module.verbose('Removing checked class'); + $module + .removeClass(className.indeterminate) + .removeClass(className.checked) + ; + if(!module.is.indeterminate() && module.is.unchecked() ) { + module.debug('Input is already unchecked'); + return; + } + module.debug('Setting state to unchecked'); + $input + .prop('indeterminate', false) + .prop('checked', false) + ; + }, + indeterminate: function() { + module.verbose('Setting class to indeterminate'); + $module + .addClass(className.indeterminate) + ; + if( module.is.indeterminate() ) { + module.debug('Input is already indeterminate, skipping input property change'); + return; + } + module.debug('Setting state to indeterminate'); + $input + .prop('indeterminate', true) + ; + }, + determinate: function() { + module.verbose('Removing indeterminate class'); + $module + .removeClass(className.indeterminate) + ; + if( module.is.determinate() ) { + module.debug('Input is already determinate, skipping input property change'); + return; + } + module.debug('Setting state to determinate'); + $input + .prop('indeterminate', false) + ; + }, + disabled: function() { + module.verbose('Setting class to disabled'); + $module + .addClass(className.disabled) + ; + if( module.is.disabled() ) { + module.debug('Input is already disabled, skipping input property change'); + return; + } + module.debug('Setting state to disabled'); + $input + .prop('disabled', 'disabled') + ; + }, + enabled: function() { + module.verbose('Removing disabled class'); + $module.removeClass(className.disabled); + if( module.is.enabled() ) { + module.debug('Input is already enabled, skipping input property change'); + return; + } + module.debug('Setting state to enabled'); + $input + .prop('disabled', false) + ; + }, + tabbable: function() { + module.verbose('Adding tabindex to checkbox'); + if( $input.attr('tabindex') === undefined) { + $input.attr('tabindex', 0); + } + } + }, + + remove: { + initialLoad: function() { + initialLoad = false; + } + }, + + trigger: { + change: function() { + var + inputElement = $input[0] + ; + if(inputElement) { + var events = document.createEvent('HTMLEvents'); + module.verbose('Triggering native change event'); + events.initEvent('change', true, false); + inputElement.dispatchEvent(events); + } + } + }, + + + create: { + label: function() { + if($input.prevAll(selector.label).length > 0) { + $input.prev(selector.label).detach().insertAfter($input); + module.debug('Moving existing label', $label); + } + else if( !module.has.label() ) { + $label = $('<label>').insertAfter($input); + module.debug('Creating label', $label); + } + } + }, + + has: { + label: function() { + return ($label.length > 0); + } + }, + + bind: { + events: function() { + module.verbose('Attaching checkbox events'); + $module + .on('click' + eventNamespace, module.event.click) + .on('change' + eventNamespace, module.event.change) + .on('keydown' + eventNamespace, selector.input, module.event.keydown) + .on('keyup' + eventNamespace, selector.input, module.event.keyup) + ; + } + }, + + unbind: { + events: function() { + module.debug('Removing events'); + $module + .off(eventNamespace) + ; + } + }, + + uncheckOthers: function() { + var + $radios = module.get.otherRadios() + ; + module.debug('Unchecking other radios', $radios); + $radios.removeClass(className.checked); + }, + + toggle: function() { + if( !module.can.change() ) { + if(!module.is.radio()) { + module.debug('Checkbox is read-only or disabled, ignoring toggle'); + } + return; + } + if( module.is.indeterminate() || module.is.unchecked() ) { + module.debug('Currently unchecked'); + module.check(); + } + else if( module.is.checked() && module.can.uncheck() ) { + module.debug('Currently checked'); + module.uncheck(); + } + }, + 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(Array.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.checkbox.settings = { + + name : 'Checkbox', + namespace : 'checkbox', + + silent : false, + debug : false, + verbose : true, + performance : true, + + // delegated event context + uncheckable : 'auto', + fireOnInit : false, + enableEnterKey : true, + + onChange : function(){}, + + beforeChecked : function(){}, + beforeUnchecked : function(){}, + beforeDeterminate : function(){}, + beforeIndeterminate : function(){}, + + onChecked : function(){}, + onUnchecked : function(){}, + + onDeterminate : function() {}, + onIndeterminate : function() {}, + + onEnable : function(){}, + onDisable : function(){}, + + // preserve misspelled callbacks (will be removed in 3.0) + onEnabled : function(){}, + onDisabled : function(){}, + + className : { + checked : 'checked', + indeterminate : 'indeterminate', + disabled : 'disabled', + hidden : 'hidden', + radio : 'radio', + readOnly : 'read-only' + }, + + error : { + method : 'The method you called is not defined' + }, + + selector : { + checkbox : '.ui.checkbox', + label : 'label, .box', + input : 'input[type="checkbox"], input[type="radio"]', + link : 'a[href]' + } + +}; + +})( jQuery, window, document ); diff --git a/semantic/src/definitions/modules/checkbox.less b/semantic/src/definitions/modules/checkbox.less new file mode 100644 index 0000000..32974de --- /dev/null +++ b/semantic/src/definitions/modules/checkbox.less @@ -0,0 +1,814 @@ +/*! + * # Fomantic-UI - Checkbox + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +/******************************* + Theme +*******************************/ + +@type : 'module'; +@element : 'checkbox'; + +@import (multiple) '../../theme.config'; + +/******************************* + Checkbox +*******************************/ + + +/*-------------- + Content +---------------*/ + +.ui.checkbox { + position: relative; + display: inline-block; + backface-visibility: hidden; + outline: none; + vertical-align: baseline; + font-style: normal; + + min-height: @checkboxSize; + font-size: @relativeMedium; + line-height: @checkboxLineHeight; + min-width: @checkboxSize; +} + +/* HTML Checkbox */ +.ui.checkbox input[type="checkbox"], +.ui.checkbox input[type="radio"] { + cursor: pointer; + position: absolute; + top: 0; + left: 0; + opacity: 0 !important; + outline: none; + z-index: 3; + width: @checkboxSize; + height: @checkboxSize; +} + + +& when (@variationCheckboxBox) { + /*-------------- + Box + ---------------*/ + + /* .box selector is deprecated and will be removed in v3 */ + .ui.checkbox .box { + &:extend(.ui.checkbox label all); + } + .ui.checkbox + .box { + &:extend(.ui.checkbox + label all); + } + .ui.checkbox input:focus ~ .box { + &:extend(.ui.checkbox input:focus ~ label all); + } + .ui.checkbox input:checked ~ .box { + &:extend(.ui.checkbox input:checked ~ label all); + } + & when (@variationCheckboxIndeterminate) { + .ui.checkbox input:not([type=radio]):indeterminate ~ .box { + &:extend(.ui.checkbox input:not([type=radio]):indeterminate ~ label all); + } + .ui.checkbox input:not([type=radio]):indeterminate:focus ~ .box { + &:extend(.ui.checkbox input:not([type=radio]):indeterminate:focus ~ label all); + } + } + .ui.checkbox input:checked:focus ~ .box { + &:extend(.ui.checkbox input:checked:focus ~ label all); + } + & when (@variationCheckboxDisabled) { + .ui.disabled.checkbox .box { + &:extend(.ui.disabled.checkbox label all); + } + + .ui.checkbox input[disabled] ~ .box { + &:extend(.ui.checkbox input[disabled] ~ label all); + } + } + & when (@variationCheckboxRadio) { + .ui.radio.checkbox .box { + &:extend(.ui.radio.checkbox label all); + } + .ui.radio.checkbox input:focus ~ .box { + &:extend(.ui.radio.checkbox input:focus ~ label all); + } + .ui.radio.checkbox input:indeterminate ~ .box { + &:extend(.ui.radio.checkbox input:indeterminate ~ label all); + } + .ui.radio.checkbox input:checked ~ .box { + &:extend(.ui.radio.checkbox input:checked ~ label all); + } + .ui.radio.checkbox input:focus:checked ~ .box { + &:extend(.ui.radio.checkbox input:focus:checked ~ label all); + } + } + & when (@variationCheckboxSlider) { + .ui.slider.checkbox .box { + &:extend(.ui.slider.checkbox label all); + } + .ui.slider.checkbox input:focus ~ .box { + &:extend(.ui.slider.checkbox input:focus ~ label all); + } + .ui.slider.checkbox input:checked ~ .box { + &:extend(.ui.slider.checkbox input:checked ~ label all); + } + .ui.slider.checkbox input:focus:checked ~ .box { + &:extend(.ui.slider.checkbox input:focus:checked ~ label all); + } + } + & when (@variationCheckboxToggle) { + .ui.toggle.checkbox .box { + &:extend(.ui.toggle.checkbox label all); + } + .ui.toggle.checkbox input ~ .box { + &:extend(.ui.toggle.checkbox input ~ label all); + } + .ui.toggle.checkbox input:focus ~ .box { + &:extend(.ui.toggle.checkbox input:focus ~ label all); + } + .ui.toggle.checkbox input:checked ~ .box { + &:extend(.ui.toggle.checkbox input:checked ~ label all); + } + .ui.toggle.checkbox input:focus:checked ~ .box { + &:extend(.ui.toggle.checkbox input:focus:checked ~ label all); + } + } + & when (@variationCheckboxFitted) { + .ui.fitted.checkbox .box { + &:extend(.ui.fitted.checkbox label all); + } + } + & when (@variationCheckboxInverted) { + .ui.inverted.checkbox .box { + &:extend(.ui.inverted.checkbox label all); + } + & when (@variationCheckboxSlider) { + .ui.inverted.slider.checkbox .box { + &:extend(.ui.inverted.slider.checkbox label all); + } + .ui.inverted.slider.checkbox input:checked ~ .box { + &:extend(.ui.inverted.slider.checkbox input:checked ~ label all); + } + .ui.inverted.slider.checkbox input:focus:checked ~ .box { + &:extend(.ui.inverted.slider.checkbox input:focus:checked ~ label all); + } + } + & when (@variationCheckboxToggle) { + .ui.inverted.toggle.checkbox .box { + &:extend(.ui.inverted.toggle.checkbox label all); + } + .ui.inverted.toggle.checkbox input:checked ~ .box { + &:extend(.ui.inverted.toggle.checkbox input:checked ~ label all); + } + .ui.inverted.toggle.checkbox input:focus:checked ~ .box { + &:extend(.ui.inverted.toggle.checkbox input:focus:checked ~ label all); + } + } + } +} + +.ui.checkbox label { + cursor: auto; + position: relative; + display: block; + padding-left: @labelDistance; + outline: none; + font-size: @labelFontSize; +} + +.ui.checkbox label:before { + position: absolute; + top: 0; + left: 0; + + width: @checkboxSize; + height: @checkboxSize; + content: ''; + + background: @checkboxBackground; + border-radius: @checkboxBorderRadius; + + transition: @checkboxTransition; + border: @checkboxBorder; +} + +/*-------------- + Checkmark +---------------*/ + +.ui.checkbox label:after { + position: absolute; + font-size: @checkboxCheckFontSize; + top: @checkboxCheckTop; + left: @checkboxCheckLeft; + width: @checkboxCheckSize; + height: @checkboxCheckSize; + text-align: center; + + opacity: 0; + color: @checkboxColor; + transition: @checkboxTransition; +} + +/*-------------- + Label +---------------*/ + +/* Inside */ +.ui.checkbox label, +.ui.checkbox + label { + color: @labelColor; + transition: @labelTransition; +} + +/* Outside */ +.ui.checkbox + label { + vertical-align: middle; +} + + +/******************************* + States +*******************************/ + + +/*-------------- + Hover +---------------*/ + +.ui.checkbox label:hover::before { + background: @checkboxHoverBackground; + border-color: @checkboxHoverBorderColor; +} +.ui.checkbox label:hover, +.ui.checkbox + label:hover { + color: @labelHoverColor; +} + +/*-------------- + Down +---------------*/ + +.ui.checkbox label:active::before { + background: @checkboxPressedBackground; + border-color: @checkboxPressedBorderColor; +} +.ui.checkbox label:active::after { + color: @checkboxPressedColor; +} +.ui.checkbox input:active ~ label { + color: @labelPressedColor; +} + +/*-------------- + Focus +---------------*/ + +.ui.checkbox input:focus ~ label:before { + background: @checkboxFocusBackground; + border-color: @checkboxFocusBorderColor; +} +.ui.checkbox input:focus ~ label:after { + color: @checkboxFocusCheckColor; +} +.ui.checkbox input:focus ~ label { + color: @labelFocusColor; +} + +/*-------------- + Active +---------------*/ + +.ui.checkbox input:checked ~ label:before { + background: @checkboxActiveBackground; + border-color: @checkboxActiveBorderColor; +} +.ui.checkbox input:checked ~ label:after { + opacity: @checkboxActiveCheckOpacity; + color: @checkboxActiveCheckColor; +} + +& when (@variationCheckboxIndeterminate){ + /*-------------- + Indeterminate + ---------------*/ + + .ui.checkbox input:not([type=radio]):indeterminate ~ label:before { + background: @checkboxIndeterminateBackground; + border-color: @checkboxIndeterminateBorderColor; + } + .ui.checkbox input:not([type=radio]):indeterminate ~ label:after { + opacity: @checkboxIndeterminateCheckOpacity; + color: @checkboxIndeterminateCheckColor; + } + .ui.indeterminate.toggle.checkbox { + & input:not([type=radio]):indeterminate ~ label:before { + background: @toggleCenterLaneBackground; + } + & input:not([type=radio]) ~ label:after { + left: @toggleCenterOffset; + } + } +} + +/*-------------- + Active Focus +---------------*/ + +.ui.checkbox input:not([type=radio]):indeterminate:focus ~ label:before, +.ui.checkbox input:checked:focus ~ label:before { + background: @checkboxActiveFocusBackground; + border-color: @checkboxActiveFocusBorderColor; +} +.ui.checkbox input:not([type=radio]):indeterminate:focus ~ label:after, +.ui.checkbox input:checked:focus ~ label:after { + color: @checkboxActiveFocusCheckColor; +} + + +/*-------------- + Read-Only +---------------*/ + +.ui.read-only.checkbox, +.ui.read-only.checkbox label { + cursor: default; +} + +& when (@variationCheckboxDisabled) { + /*-------------- + Disabled + ---------------*/ + + .ui.disabled.checkbox label, + .ui.checkbox input[disabled] ~ label { + cursor: default !important; + opacity: @disabledCheckboxOpacity; + color: @disabledCheckboxLabelColor; + pointer-events: none; + } +} + +/*-------------- + Hidden +---------------*/ + +/* Initialized checkbox moves input below element + to prevent manually triggering */ +.ui.checkbox input.hidden { + z-index: -1; +} + +/* Selectable Label */ +.ui.checkbox input.hidden + label { + cursor: pointer; + user-select: none; +} + + +/******************************* + Types +*******************************/ + +& when (@variationCheckboxRadio) { + /*-------------- + Radio + ---------------*/ + + .ui.radio.checkbox { + min-height: @radioSize; + } + + .ui.radio.checkbox label { + padding-left: @radioLabelDistance; + } + + /* Box */ + .ui.radio.checkbox label:before { + content: ''; + transform: none; + + width: @radioSize; + height: @radioSize; + border-radius: @circularRadius; + top: @radioTop; + left: @radioLeft; + } + + /* Bullet */ + .ui.radio.checkbox label:after { + border: none; + content: '' !important; + line-height: @radioSize; + top: @bulletTop; + left: @bulletLeft; + width: @radioSize; + height: @radioSize; + border-radius: @bulletRadius; + transform: scale(@bulletScale); + background-color: @bulletColor; + } + + /* Focus */ + .ui.radio.checkbox input:focus ~ label:before { + background-color: @radioFocusBackground; + } + .ui.radio.checkbox input:focus ~ label:after { + background-color: @radioFocusBulletColor; + } + + /* Indeterminate */ + .ui.radio.checkbox input:indeterminate ~ label:after { + opacity: 0; + } + + /* Active */ + .ui.radio.checkbox input:checked ~ label:before { + background-color: @radioActiveBackground; + } + .ui.radio.checkbox input:checked ~ label:after { + background-color: @radioActiveBulletColor; + } + + /* Active Focus */ + .ui.radio.checkbox input:focus:checked ~ label:before { + background-color: @radioActiveFocusBackground; + } + .ui.radio.checkbox input:focus:checked ~ label:after { + background-color: @radioActiveFocusBulletColor; + } +} + +& when (@variationCheckboxSlider) { + /*-------------- + Slider + ---------------*/ + + .ui.slider.checkbox { + min-height: @sliderHeight; + } + + /* Input */ + .ui.slider.checkbox input { + width: @sliderWidth; + height: @sliderHeight; + } + + /* Label */ + .ui.slider.checkbox label { + padding-left: @sliderLabelDistance; + line-height: @sliderLabelLineHeight; + color: @sliderOffLabelColor; + } + + /* Line */ + .ui.slider.checkbox label:before { + display: block; + position: absolute; + content: ''; + transform: none; + border: none !important; + left: 0; + z-index: 1; + + top: @sliderLineVerticalOffset; + + background-color: @sliderLineColor; + width: @sliderLineWidth; + height: @sliderLineHeight; + + border-radius: @sliderLineRadius; + transition: @sliderLineTransition; + + } + + /* Handle */ + .ui.slider.checkbox label:after { + background: @handleBackground; + position: absolute; + content: '' !important; + opacity: 1; + z-index: 2; + + border: none; + box-shadow: @handleBoxShadow; + width: @sliderHandleSize; + height: @sliderHandleSize; + top: @sliderHandleOffset; + left: 0; + transform: none; + + border-radius: @circularRadius; + transition: @sliderHandleTransition; + } + + /* Focus */ + .ui.slider.checkbox input:focus ~ label:before { + background-color: @toggleFocusColor; + border: none; + } + + /* Hover */ + .ui.slider.checkbox label:hover { + color: @sliderHoverLabelColor; + } + .ui.slider.checkbox label:hover::before { + background: @sliderHoverLaneBackground; + } + + /* Active */ + .ui.slider.checkbox input:checked ~ label { + color: @sliderOnLabelColor !important; + } + .ui.slider.checkbox input:checked ~ label:before { + background-color: @sliderOnLineColor !important; + } + .ui.slider.checkbox input:checked ~ label:after { + left: @sliderTravelDistance; + } + + /* Active Focus */ + .ui.slider.checkbox input:focus:checked ~ label { + color: @sliderOnFocusLabelColor !important; + } + .ui.slider.checkbox input:focus:checked ~ label:before { + background-color: @sliderOnFocusLineColor !important; + } +} + +& when (@variationCheckboxToggle) { + /*-------------- + Toggle + ---------------*/ + + .ui.toggle.checkbox { + min-height: @toggleHeight; + } + + /* Input */ + .ui.toggle.checkbox input { + width: @toggleWidth; + height: @toggleHeight; + } + + /* Label */ + .ui.toggle.checkbox label { + min-height: @toggleHandleSize; + padding-left: @toggleLabelDistance; + color: @toggleOffLabelColor; + } + .ui.toggle.checkbox label { + padding-top: @toggleLabelOffset; + } + + /* Switch */ + .ui.toggle.checkbox label:before { + display: block; + position: absolute; + content: ''; + z-index: 1; + transform: none; + border: none; + + top: @toggleLaneVerticalOffset; + + background: @toggleLaneBackground; + box-shadow: @toggleLaneBoxShadow; + width: @toggleLaneWidth; + height: @toggleLaneHeight; + border-radius: @toggleHandleRadius; + } + + /* Handle */ + .ui.toggle.checkbox label:after { + background: @handleBackground; + position: absolute; + content: '' !important; + opacity: 1; + z-index: 2; + + border: none; + box-shadow: @handleBoxShadow; + width: @toggleHandleSize; + height: @toggleHandleSize; + top: @toggleHandleOffset; + left: 0; + + border-radius: @circularRadius; + transition: @toggleHandleTransition; + } + + .ui.toggle.checkbox input ~ label:after { + left: @toggleOffOffset; + box-shadow: @toggleOffHandleBoxShadow; + } + + /* Focus */ + .ui.toggle.checkbox input:focus ~ label:before { + background-color: @toggleFocusColor; + border: none; + } + + /* Hover */ + .ui.toggle.checkbox label:hover::before { + background-color: @toggleHoverColor; + border: none; + } + + /* Active */ + .ui.toggle.checkbox input:checked ~ label { + color: @toggleOnLabelColor !important; + } + .ui.toggle.checkbox input:checked ~ label:before { + background-color: @toggleOnLaneColor !important; + } + .ui.toggle.checkbox input:checked ~ label:after { + left: @toggleOnOffset; + box-shadow: @toggleOnHandleBoxShadow; + } + + + /* Active Focus */ + .ui.toggle.checkbox input:focus:checked ~ label { + color: @toggleOnFocusLabelColor !important; + } + .ui.toggle.checkbox input:focus:checked ~ label:before { + background-color: @toggleOnFocusLaneColor !important; + } +} + +/******************************* + Variations +*******************************/ +& when (@variationCheckboxFitted) { + /*-------------- + Fitted + ---------------*/ + + .ui.fitted.checkbox label { + padding-left: 0 !important; + } + + .ui.fitted.toggle.checkbox { + width: @toggleWidth; + } + + .ui.fitted.slider.checkbox { + width: @sliderWidth; + } +} + +& when (@variationCheckboxInverted) { + /*-------------- + Inverted + ---------------*/ + .ui.inverted.checkbox label, + .ui.inverted.checkbox + label { + color: @invertedTextColor !important; + } + + /* Hover */ + .ui.inverted.checkbox label:hover { + color: @invertedHoveredTextColor !important; + } + .ui.inverted.checkbox label:hover::before { + border-color: @strongSelectedBorderColor; + } + & when (@variationCheckboxSlider) { + /*Slider Label */ + .ui.inverted.slider.checkbox label { + color: @invertedUnselectedTextColor; + } + + /* Slider Line */ + .ui.inverted.slider.checkbox label:before { + background-color: @invertedUnselectedTextColor !important; + } + + /* Slider Hover */ + .ui.inverted.slider.checkbox label:hover::before { + background: @invertedLightTextColor !important; + } + + /* Slider Active */ + .ui.inverted.slider.checkbox input:checked ~ label { + color: @invertedSelectedTextColor !important; + } + .ui.inverted.slider.checkbox input:checked ~ label:before { + background-color: @selectedWhiteBorderColor !important; + } + + /* Slider Active Focus */ + .ui.inverted.slider.checkbox input:focus:checked ~ label { + color: @invertedSelectedTextColor !important; + } + .ui.inverted.slider.checkbox input:focus:checked ~ label:before { + background-color: @selectedWhiteBorderColor !important; + } + } + & when (@variationCheckboxToggle) { + /* Toggle Switch */ + .ui.inverted.toggle.checkbox label:before { + background-color: @invertedTextColor !important; + } + + /* Toggle Hover */ + .ui.inverted.toggle.checkbox label:hover::before { + background: @invertedHoveredTextColor !important; + } + + /* Toggle Active */ + .ui.inverted.toggle.checkbox input:checked ~ label { + color: @invertedSelectedTextColor !important; + } + .ui.inverted.toggle.checkbox input:checked ~ label:before { + background-color: @toggleOnLaneColor !important; + } + + /* Toggle Active Focus */ + .ui.inverted.toggle.checkbox input:focus:checked ~ label { + color: @invertedSelectedTextColor !important; + } + .ui.inverted.toggle.checkbox input:focus:checked ~ label:before { + background-color: @toggleOnFocusLaneColor !important; + } + } +} + +/*-------------------- + Size +---------------------*/ + +each(@variationCheckboxSizes, { + @raw: @{value}Raw; + @size: @{value}CheckboxSize; + @circleScale: @{value}CheckboxCircleScale; + @circleLeft: @{value}CheckboxCircleLeft; + + .ui.@{value}.checkbox { + font-size: @@size; + } + + & when (@@raw > 1) { + .ui.@{value}.form .checkbox, + .ui.@{value}.checkbox { + &:not(.slider):not(.toggle):not(.radio) { + & + label:after, + label:before { + transform: scale(@@raw); + transform-origin:left; + } + } + &.radio when (@variationCheckboxRadio) { + & + label:before { + transform: scale(@@raw); + transform-origin:left; + } + & + label:after { + transform:scale(@@circleScale); + transform-origin:left; + left: @@circleLeft; + } + } + } + } + & when (@@raw > 1) and (@variationCheckboxBox) { + .ui.@{value}.form .checkbox, + .ui.@{value}.checkbox { + &:not(.slider):not(.toggle):not(.radio) { + & + .box:after, + .box:before { + transform: scale(@@raw); + transform-origin:left; + } + } + &.radio when (@variationCheckboxRadio) { + & + .box:before { + transform: scale(@@raw); + transform-origin:left; + } + & + .box:after { + transform:scale(@@circleScale); + transform-origin:left; + left: @@circleLeft; + } + } + } + } +}) + +.loadUIOverrides(); diff --git a/semantic/src/definitions/modules/dimmer.js b/semantic/src/definitions/modules/dimmer.js new file mode 100644 index 0000000..9429a9e --- /dev/null +++ b/semantic/src/definitions/modules/dimmer.js @@ -0,0 +1,753 @@ +/*! + * # Fomantic-UI - Dimmer + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +'use strict'; + +$.isFunction = $.isFunction || function(obj) { + return typeof obj === "function" && typeof obj.nodeType !== "number"; +}; + +window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.fn.dimmer = function(parameters) { + var + $allModules = $(this), + + time = new Date().getTime(), + performance = [], + + query = arguments[0], + methodInvoked = (typeof query == 'string'), + queryArguments = [].slice.call(arguments, 1), + + returnedValue + ; + + $allModules + .each(function() { + var + settings = ( $.isPlainObject(parameters) ) + ? $.extend(true, {}, $.fn.dimmer.settings, parameters) + : $.extend({}, $.fn.dimmer.settings), + + selector = settings.selector, + namespace = settings.namespace, + className = settings.className, + error = settings.error, + + eventNamespace = '.' + namespace, + moduleNamespace = 'module-' + namespace, + moduleSelector = $allModules.selector || '', + + clickEvent = ('ontouchstart' in document.documentElement) + ? 'touchstart' + : 'click', + + $module = $(this), + $dimmer, + $dimmable, + + element = this, + instance = $module.data(moduleNamespace), + module + ; + + module = { + + preinitialize: function() { + if( module.is.dimmer() ) { + + $dimmable = $module.parent(); + $dimmer = $module; + } + else { + $dimmable = $module; + if( module.has.dimmer() ) { + if(settings.dimmerName) { + $dimmer = $dimmable.find(selector.dimmer).filter('.' + settings.dimmerName); + } + else { + $dimmer = $dimmable.find(selector.dimmer); + } + } + else { + $dimmer = module.create(); + } + } + }, + + initialize: function() { + module.debug('Initializing dimmer', settings); + + module.bind.events(); + module.set.dimmable(); + module.instantiate(); + }, + + instantiate: function() { + module.verbose('Storing instance of module', module); + instance = module; + $module + .data(moduleNamespace, instance) + ; + }, + + destroy: function() { + module.verbose('Destroying previous module', $dimmer); + module.unbind.events(); + module.remove.variation(); + $dimmable + .off(eventNamespace) + ; + }, + + bind: { + events: function() { + if(settings.on == 'hover') { + $dimmable + .on('mouseenter' + eventNamespace, module.show) + .on('mouseleave' + eventNamespace, module.hide) + ; + } + else if(settings.on == 'click') { + $dimmable + .on(clickEvent + eventNamespace, module.toggle) + ; + } + if( module.is.page() ) { + module.debug('Setting as a page dimmer', $dimmable); + module.set.pageDimmer(); + } + + if( module.is.closable() ) { + module.verbose('Adding dimmer close event', $dimmer); + $dimmable + .on(clickEvent + eventNamespace, selector.dimmer, module.event.click) + ; + } + } + }, + + unbind: { + events: function() { + $module + .removeData(moduleNamespace) + ; + $dimmable + .off(eventNamespace) + ; + } + }, + + event: { + click: function(event) { + module.verbose('Determining if event occured on dimmer', event); + if( $dimmer.find(event.target).length === 0 || $(event.target).is(selector.content) ) { + module.hide(); + event.stopImmediatePropagation(); + } + } + }, + + addContent: function(element) { + var + $content = $(element) + ; + module.debug('Add content to dimmer', $content); + if($content.parent()[0] !== $dimmer[0]) { + $content.detach().appendTo($dimmer); + } + }, + + create: function() { + var + $element = $( settings.template.dimmer(settings) ) + ; + if(settings.dimmerName) { + module.debug('Creating named dimmer', settings.dimmerName); + $element.addClass(settings.dimmerName); + } + $element + .appendTo($dimmable) + ; + return $element; + }, + + show: function(callback) { + callback = $.isFunction(callback) + ? callback + : function(){} + ; + module.debug('Showing dimmer', $dimmer, settings); + module.set.variation(); + if( (!module.is.dimmed() || module.is.animating()) && module.is.enabled() ) { + module.animate.show(callback); + settings.onShow.call(element); + settings.onChange.call(element); + } + else { + module.debug('Dimmer is already shown or disabled'); + } + }, + + hide: function(callback) { + callback = $.isFunction(callback) + ? callback + : function(){} + ; + if( module.is.dimmed() || module.is.animating() ) { + module.debug('Hiding dimmer', $dimmer); + module.animate.hide(callback); + settings.onHide.call(element); + settings.onChange.call(element); + } + else { + module.debug('Dimmer is not visible'); + } + }, + + toggle: function() { + module.verbose('Toggling dimmer visibility', $dimmer); + if( !module.is.dimmed() ) { + module.show(); + } + else { + if ( module.is.closable() ) { + module.hide(); + } + } + }, + + animate: { + show: function(callback) { + callback = $.isFunction(callback) + ? callback + : function(){} + ; + if(settings.useCSS && $.fn.transition !== undefined && $dimmer.transition('is supported')) { + if(settings.useFlex) { + module.debug('Using flex dimmer'); + module.remove.legacy(); + } + else { + module.debug('Using legacy non-flex dimmer'); + module.set.legacy(); + } + if(settings.opacity !== 'auto') { + module.set.opacity(); + } + $dimmer + .transition({ + displayType : settings.useFlex + ? 'flex' + : 'block', + animation : settings.transition + ' in', + queue : false, + duration : module.get.duration(), + useFailSafe : true, + onStart : function() { + module.set.dimmed(); + }, + onComplete : function() { + module.set.active(); + callback(); + } + }) + ; + } + else { + module.verbose('Showing dimmer animation with javascript'); + module.set.dimmed(); + if(settings.opacity == 'auto') { + settings.opacity = 0.8; + } + $dimmer + .stop() + .css({ + opacity : 0, + width : '100%', + height : '100%' + }) + .fadeTo(module.get.duration(), settings.opacity, function() { + $dimmer.removeAttr('style'); + module.set.active(); + callback(); + }) + ; + } + }, + hide: function(callback) { + callback = $.isFunction(callback) + ? callback + : function(){} + ; + if(settings.useCSS && $.fn.transition !== undefined && $dimmer.transition('is supported')) { + module.verbose('Hiding dimmer with css'); + $dimmer + .transition({ + displayType : settings.useFlex + ? 'flex' + : 'block', + animation : settings.transition + ' out', + queue : false, + duration : module.get.duration(), + useFailSafe : true, + onComplete : function() { + module.remove.dimmed(); + module.remove.variation(); + module.remove.active(); + callback(); + } + }) + ; + } + else { + module.verbose('Hiding dimmer with javascript'); + $dimmer + .stop() + .fadeOut(module.get.duration(), function() { + module.remove.dimmed(); + module.remove.active(); + $dimmer.removeAttr('style'); + callback(); + }) + ; + } + } + }, + + get: { + dimmer: function() { + return $dimmer; + }, + duration: function() { + if(typeof settings.duration == 'object') { + if( module.is.active() ) { + return settings.duration.hide; + } + else { + return settings.duration.show; + } + } + return settings.duration; + } + }, + + has: { + dimmer: function() { + if(settings.dimmerName) { + return ($module.find(selector.dimmer).filter('.' + settings.dimmerName).length > 0); + } + else { + return ( $module.find(selector.dimmer).length > 0 ); + } + } + }, + + is: { + active: function() { + return $dimmer.hasClass(className.active); + }, + animating: function() { + return ( $dimmer.is(':animated') || $dimmer.hasClass(className.animating) ); + }, + closable: function() { + if(settings.closable == 'auto') { + if(settings.on == 'hover') { + return false; + } + return true; + } + return settings.closable; + }, + dimmer: function() { + return $module.hasClass(className.dimmer); + }, + dimmable: function() { + return $module.hasClass(className.dimmable); + }, + dimmed: function() { + return $dimmable.hasClass(className.dimmed); + }, + disabled: function() { + return $dimmable.hasClass(className.disabled); + }, + enabled: function() { + return !module.is.disabled(); + }, + page: function () { + return $dimmable.is('body'); + }, + pageDimmer: function() { + return $dimmer.hasClass(className.pageDimmer); + } + }, + + can: { + show: function() { + return !$dimmer.hasClass(className.disabled); + } + }, + + set: { + opacity: function(opacity) { + var + color = $dimmer.css('background-color'), + colorArray = color.split(','), + isRGB = (colorArray && colorArray.length >= 3) + ; + opacity = settings.opacity === 0 ? 0 : settings.opacity || opacity; + if(isRGB) { + colorArray[2] = colorArray[2].replace(')',''); + colorArray[3] = opacity + ')'; + color = colorArray.join(','); + } + else { + color = 'rgba(0, 0, 0, ' + opacity + ')'; + } + module.debug('Setting opacity to', opacity); + $dimmer.css('background-color', color); + }, + legacy: function() { + $dimmer.addClass(className.legacy); + }, + active: function() { + $dimmer.addClass(className.active); + }, + dimmable: function() { + $dimmable.addClass(className.dimmable); + }, + dimmed: function() { + $dimmable.addClass(className.dimmed); + }, + pageDimmer: function() { + $dimmer.addClass(className.pageDimmer); + }, + disabled: function() { + $dimmer.addClass(className.disabled); + }, + variation: function(variation) { + variation = variation || settings.variation; + if(variation) { + $dimmer.addClass(variation); + } + } + }, + + remove: { + active: function() { + $dimmer + .removeClass(className.active) + ; + }, + legacy: function() { + $dimmer.removeClass(className.legacy); + }, + dimmed: function() { + $dimmable.removeClass(className.dimmed); + }, + disabled: function() { + $dimmer.removeClass(className.disabled); + }, + variation: function(variation) { + variation = variation || settings.variation; + if(variation) { + $dimmer.removeClass(variation); + } + } + }, + + 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($allModules.length > 1) { + title += ' ' + '(' + $allModules.length + ')'; + } + 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(Array.isArray(returnedValue)) { + returnedValue.push(response); + } + else if(returnedValue !== undefined) { + returnedValue = [returnedValue, response]; + } + else if(response !== undefined) { + returnedValue = response; + } + return found; + } + }; + + module.preinitialize(); + + 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.dimmer.settings = { + + name : 'Dimmer', + namespace : 'dimmer', + + silent : false, + debug : false, + verbose : false, + performance : true, + + // whether should use flex layout + useFlex : true, + + // name to distinguish between multiple dimmers in context + dimmerName : false, + + // whether to add a variation type + variation : false, + + // whether to bind close events + closable : 'auto', + + // whether to use css animations + useCSS : true, + + // css animation to use + transition : 'fade', + + // event to bind to + on : false, + + // overriding opacity value + opacity : 'auto', + + // transition durations + duration : { + show : 500, + hide : 500 + }, +// whether the dynamically created dimmer should have a loader + displayLoader: false, + loaderText : false, + loaderVariation : '', + + onChange : function(){}, + onShow : function(){}, + onHide : function(){}, + + error : { + method : 'The method you called is not defined.' + }, + + className : { + active : 'active', + animating : 'animating', + dimmable : 'dimmable', + dimmed : 'dimmed', + dimmer : 'dimmer', + disabled : 'disabled', + hide : 'hide', + legacy : 'legacy', + pageDimmer : 'page', + show : 'show', + loader : 'ui loader' + }, + + selector: { + dimmer : '> .ui.dimmer', + content : '.ui.dimmer > .content, .ui.dimmer > .content > .center' + }, + + template: { + dimmer: function(settings) { + var d = $('<div/>').addClass('ui dimmer'),l; + if(settings.displayLoader) { + l = $('<div/>') + .addClass(settings.className.loader) + .addClass(settings.loaderVariation); + if(!!settings.loaderText){ + l.text(settings.loaderText); + l.addClass('text'); + } + d.append(l); + } + return d; + } + } + +}; + +})( jQuery, window, document ); diff --git a/semantic/src/definitions/modules/dimmer.less b/semantic/src/definitions/modules/dimmer.less new file mode 100644 index 0000000..04c3f54 --- /dev/null +++ b/semantic/src/definitions/modules/dimmer.less @@ -0,0 +1,390 @@ +/*! + * # Fomantic-UI - Dimmer + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +/******************************* + Theme +*******************************/ + +@type : 'module'; +@element : 'dimmer'; + +@import (multiple) '../../theme.config'; + +/******************************* + Dimmer +*******************************/ + +.dimmable:not(body) { + position: @dimmablePosition; +} + +.ui.dimmer { + display: none; + position: @dimmerPosition; + top: 0 !important; + left: 0 !important; + + width: 100%; + height: 100%; + + text-align: @textAlign; + vertical-align: @verticalAlign; + padding: @padding; + + background: @backgroundColor; + opacity: @hiddenOpacity; + line-height: @lineHeight; + + animation-fill-mode: both; + animation-duration: @duration; + transition: @transition; + + flex-direction: column; + align-items: center; + justify-content: center; + + user-select: none; + will-change: opacity; + z-index: @zIndex; +} + +/* Dimmer Content */ +.ui.dimmer > .content { + user-select: text; + color: @textColor; +} + + +/* Loose Coupling */ +.ui.segment > .ui.dimmer:not(.page) { + border-radius: inherit; +} + +/* Scrollbars */ +.addScrollbars() when (@useCustomScrollbars) { + .ui.dimmer:not(.inverted)::-webkit-scrollbar-track { + background: @trackInvertedBackground; + } + .ui.dimmer:not(.inverted)::-webkit-scrollbar-thumb { + background: @thumbInvertedBackground; + } + .ui.dimmer:not(.inverted)::-webkit-scrollbar-thumb:window-inactive { + background: @thumbInvertedInactiveBackground; + } + .ui.dimmer:not(.inverted)::-webkit-scrollbar-thumb:hover { + background: @thumbInvertedHoverBackground; + } +} +.addScrollbars(); + +/******************************* + States +*******************************/ + +/* Animating */ +.animating.dimmable:not(body), +.dimmed.dimmable:not(body) { + overflow: @overflow; +} + +/* Animating / Active / Visible */ +.dimmed.dimmable > .ui.animating.dimmer, +.dimmed.dimmable > .ui.visible.dimmer, +.ui.active.dimmer { + display: flex; + opacity: @visibleOpacity; +} + +& when (@variationDimmerDisabled) { + /* Disabled */ + .ui.disabled.dimmer { + width: 0 !important; + height: 0 !important; + } +} + + +/******************************* + Variations +*******************************/ + +& when (@variationDimmerLegacy) { + /*-------------- + Legacy + ---------------*/ + + /* Animating / Active / Visible */ + .dimmed.dimmable > .ui.animating.legacy.dimmer, + .dimmed.dimmable > .ui.visible.legacy.dimmer, + .ui.active.legacy.dimmer { + display: block; + } +} + +& when (@variationDimmerAligned) { + /*-------------- + Alignment + ---------------*/ + + .ui[class*="top aligned"].dimmer { + justify-content: flex-start; + } + .ui[class*="bottom aligned"].dimmer { + justify-content: flex-end; + } +} + +& when (@variationDimmerPage) { + /*-------------- + Page + ---------------*/ + + .ui.page.dimmer { + position: @pageDimmerPosition; + transform-style: @transformStyle; + perspective: @perspective; + transform-origin: center center; + &.modals { + -moz-perspective: none; + } + } +} + +body.animating.in.dimmable, +body.dimmed.dimmable { + overflow: hidden; +} + +body.dimmable > .dimmer { + position: fixed; +} + +& when (@variationDimmerBlurring) { + /*-------------- + Blurring + ---------------*/ + + .blurring.dimmable > :not(.dimmer) { + filter: @blurredStartFilter; + transition: @blurredTransition; + } + .blurring.dimmed.dimmable > :not(.dimmer):not(.popup) { + filter: @blurredEndFilter; + } + + /* Dimmer Color */ + .blurring.dimmable > .dimmer { + background: @blurredBackgroundColor; + } + .blurring.dimmable > .inverted.dimmer { + background: @blurredInvertedBackgroundColor; + } +} +& when (@variationDimmerAligned) { + /*-------------- + Aligned + ---------------*/ + + .ui.dimmer > .top.aligned.content > * { + vertical-align: top; + } + .ui.dimmer > .bottom.aligned.content > * { + vertical-align: bottom; + } +} + +& when (@variationDimmerShades) { + /*-------------- + Shades + ---------------*/ + + .medium.medium.medium.medium.medium.dimmer { + background: @mediumBackgroundColor; + } + .light.light.light.light.light.dimmer { + background: @lightBackgroundColor; + } + .very.light.light.light.light.dimmer { + background: @veryLightBackgroundColor; + } +} + +& when (@variationDimmerInverted) { + /*-------------- + Inverted + ---------------*/ + + .ui.inverted.dimmer { + background: @invertedBackgroundColor; + } + .ui.inverted.dimmer > .content, + .ui.inverted.dimmer > .content > * { + color: @invertedTextColor; + } + + & when (@variationDimmerShades) { + /*-------------- + Inverted Shades + ---------------*/ + + .medium.medium.medium.medium.medium.inverted.dimmer { + background: @mediumInvertedBackgroundColor; + } + .light.light.light.light.light.inverted.dimmer { + background: @lightInvertedBackgroundColor; + } + .very.light.light.light.light.inverted.dimmer { + background: @veryLightInvertedBackgroundColor; + } + } +} + +& when (@variationDimmerSimple) { + /*-------------- + Simple + ---------------*/ + + /* Displays without javascript */ + .ui.simple.dimmer { + display: block; + overflow: hidden; + opacity: 0; + width: 0; + height: 0; + z-index: -100; + background: @simpleStartBackgroundColor; + } + .dimmed.dimmable > .ui.simple.dimmer { + overflow: visible; + opacity: 1; + width: 100%; + height: 100%; + background: @simpleEndBackgroundColor; + z-index: @simpleZIndex; + } + + .ui.simple.inverted.dimmer { + background: @simpleInvertedStartBackgroundColor; + } + .dimmed.dimmable > .ui.simple.inverted.dimmer { + background: @simpleInvertedEndBackgroundColor; + } +} + +& when (@variationDimmerPartially) { + /*-------------- + Partially + ----------------*/ + + .ui[class*="top dimmer"], + .ui[class*="center dimmer"], + .ui[class*="bottom dimmer"] { + height: auto; + } + .ui[class*="bottom dimmer"] { + top: auto !important; + bottom: 0; + } + .ui[class*="center dimmer"] { + top:50% !important; + transform: translateY(-50%); + -webkit-transform: translateY(calc(-50% - .5px)); + } + + .ui.segment > .ui.ui[class*="top dimmer"] { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } + .ui.segment > .ui.ui[class*="center dimmer"] { + border-radius: 0; + } + .ui.segment > .ui.ui[class*="bottom dimmer"] { + border-top-left-radius: 0; + border-top-right-radius: 0; + } + + .ui[class*="center dimmer"].transition[class*="fade up"].in { + animation-name: fadeInUpCenter; + } + .ui[class*="center dimmer"].transition[class*="fade down"].in { + animation-name: fadeInDownCenter; + } + .ui[class*="center dimmer"].transition[class*="fade up"].out { + animation-name: fadeOutUpCenter; + } + .ui[class*="center dimmer"].transition[class*="fade down"].out { + animation-name: fadeOutDownCenter; + } + .ui[class*="center dimmer"].bounce.transition { + animation-name: bounceCenter; + } + @keyframes fadeInUpCenter { + 0% { + opacity: 0; + transform: translateY(-40%); + -webkit-transform: translateY(calc(-40% - .5px)); + } + 100% { + opacity: 1; + transform: translateY(-50%); + -webkit-transform: translateY(calc(-50% - .5px)); + } + } + @keyframes fadeInDownCenter { + 0% { + opacity: 0; + transform: translateY(-60%); + -webkit-transform: translateY(calc(-60% - .5px)); + } + 100% { + opacity: 1; + transform: translateY(-50%); + -webkit-transform: translateY(calc(-50% - .5px)); + } + } + @keyframes fadeOutUpCenter { + 0% { + opacity: 1; + transform: translateY(-50%); + -webkit-transform: translateY(calc(-50% - .5px)); + } + 100% { + opacity: 0; + transform: translateY(-45%); + -webkit-transform: translateY(calc(-45% - .5px)); + } + } + @keyframes fadeOutDownCenter { + 0% { + opacity: 1; + transform: translateY(-50%); + -webkit-transform: translateY(calc(-50% - .5px)); + } + 100% { + opacity: 0; + transform: translateY(-55%); + -webkit-transform: translateY(calc(-55% - .5px)); + } + } + @keyframes bounceCenter { + 0%, 20%, 50%, 80%, 100% { + transform: translateY(-50%); + -webkit-transform: translateY(calc(-50% - .5px)); + } + 40% { + transform: translateY(calc(-50% - 30px)); + } + 60% { + transform: translateY(calc(-50% - 15px)); + } + } +} + +.loadUIOverrides(); diff --git a/semantic/src/definitions/modules/dropdown.js b/semantic/src/definitions/modules/dropdown.js new file mode 100644 index 0000000..9edd33d --- /dev/null +++ b/semantic/src/definitions/modules/dropdown.js @@ -0,0 +1,4238 @@ +/*! + * # Fomantic-UI - Dropdown + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +'use strict'; + +$.isFunction = $.isFunction || function(obj) { + return typeof obj === "function" && typeof obj.nodeType !== "number"; +}; + +window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.fn.dropdown = function(parameters) { + var + $allModules = $(this), + $document = $(document), + + moduleSelector = $allModules.selector || '', + + hasTouch = ('ontouchstart' in document.documentElement), + clickEvent = hasTouch + ? 'touchstart' + : 'click', + + time = new Date().getTime(), + performance = [], + + query = arguments[0], + methodInvoked = (typeof query == 'string'), + queryArguments = [].slice.call(arguments, 1), + returnedValue + ; + + $allModules + .each(function(elementIndex) { + var + settings = ( $.isPlainObject(parameters) ) + ? $.extend(true, {}, $.fn.dropdown.settings, parameters) + : $.extend({}, $.fn.dropdown.settings), + + className = settings.className, + message = settings.message, + fields = settings.fields, + keys = settings.keys, + metadata = settings.metadata, + namespace = settings.namespace, + regExp = settings.regExp, + selector = settings.selector, + error = settings.error, + templates = settings.templates, + + eventNamespace = '.' + namespace, + moduleNamespace = 'module-' + namespace, + + $module = $(this), + $context = $(settings.context), + $text = $module.find(selector.text), + $search = $module.find(selector.search), + $sizer = $module.find(selector.sizer), + $input = $module.find(selector.input), + $icon = $module.find(selector.icon), + $clear = $module.find(selector.clearIcon), + + $combo = ($module.prev().find(selector.text).length > 0) + ? $module.prev().find(selector.text) + : $module.prev(), + + $menu = $module.children(selector.menu), + $item = $menu.find(selector.item), + $divider = settings.hideDividers ? $item.parent().children(selector.divider) : $(), + + activated = false, + itemActivated = false, + internalChange = false, + iconClicked = false, + element = this, + instance = $module.data(moduleNamespace), + + selectActionActive, + initialLoad, + pageLostFocus, + willRefocus, + elementNamespace, + id, + selectObserver, + menuObserver, + classObserver, + module + ; + + module = { + + initialize: function() { + module.debug('Initializing dropdown', settings); + + if( module.is.alreadySetup() ) { + module.setup.reference(); + } + else { + if (settings.ignoreDiacritics && !String.prototype.normalize) { + settings.ignoreDiacritics = false; + module.error(error.noNormalize, element); + } + + module.setup.layout(); + + if(settings.values) { + module.set.initialLoad(); + module.change.values(settings.values); + module.remove.initialLoad(); + } + + module.refreshData(); + + module.save.defaults(); + module.restore.selected(); + + module.create.id(); + module.bind.events(); + + module.observeChanges(); + module.instantiate(); + } + + }, + + instantiate: function() { + module.verbose('Storing instance of dropdown', module); + instance = module; + $module + .data(moduleNamespace, module) + ; + }, + + destroy: function() { + module.verbose('Destroying previous dropdown', $module); + module.remove.tabbable(); + module.remove.active(); + $menu.transition('stop all'); + $menu.removeClass(className.visible).addClass(className.hidden); + $module + .off(eventNamespace) + .removeData(moduleNamespace) + ; + $menu + .off(eventNamespace) + ; + $document + .off(elementNamespace) + ; + module.disconnect.menuObserver(); + module.disconnect.selectObserver(); + module.disconnect.classObserver(); + }, + + observeChanges: function() { + if('MutationObserver' in window) { + selectObserver = new MutationObserver(module.event.select.mutation); + menuObserver = new MutationObserver(module.event.menu.mutation); + classObserver = new MutationObserver(module.event.class.mutation); + module.debug('Setting up mutation observer', selectObserver, menuObserver, classObserver); + module.observe.select(); + module.observe.menu(); + module.observe.class(); + } + }, + + disconnect: { + menuObserver: function() { + if(menuObserver) { + menuObserver.disconnect(); + } + }, + selectObserver: function() { + if(selectObserver) { + selectObserver.disconnect(); + } + }, + classObserver: function() { + if(classObserver) { + classObserver.disconnect(); + } + } + }, + observe: { + select: function() { + if(module.has.input() && selectObserver) { + selectObserver.observe($module[0], { + childList : true, + subtree : true + }); + } + }, + menu: function() { + if(module.has.menu() && menuObserver) { + menuObserver.observe($menu[0], { + childList : true, + subtree : true + }); + } + }, + class: function() { + if(module.has.search() && classObserver) { + classObserver.observe($module[0], { + attributes : true + }); + } + } + }, + + create: { + id: function() { + id = (Math.random().toString(16) + '000000000').substr(2, 8); + elementNamespace = '.' + id; + module.verbose('Creating unique id for element', id); + }, + userChoice: function(values) { + var + $userChoices, + $userChoice, + isUserValue, + html + ; + values = values || module.get.userValues(); + if(!values) { + return false; + } + values = Array.isArray(values) + ? values + : [values] + ; + $.each(values, function(index, value) { + if(module.get.item(value) === false) { + html = settings.templates.addition( module.add.variables(message.addResult, value) ); + $userChoice = $('<div />') + .html(html) + .attr('data-' + metadata.value, value) + .attr('data-' + metadata.text, value) + .addClass(className.addition) + .addClass(className.item) + ; + if(settings.hideAdditions) { + $userChoice.addClass(className.hidden); + } + $userChoices = ($userChoices === undefined) + ? $userChoice + : $userChoices.add($userChoice) + ; + module.verbose('Creating user choices for value', value, $userChoice); + } + }); + return $userChoices; + }, + userLabels: function(value) { + var + userValues = module.get.userValues() + ; + if(userValues) { + module.debug('Adding user labels', userValues); + $.each(userValues, function(index, value) { + module.verbose('Adding custom user value'); + module.add.label(value, value); + }); + } + }, + menu: function() { + $menu = $('<div />') + .addClass(className.menu) + .appendTo($module) + ; + }, + sizer: function() { + $sizer = $('<span />') + .addClass(className.sizer) + .insertAfter($search) + ; + } + }, + + search: function(query) { + query = (query !== undefined) + ? query + : module.get.query() + ; + module.verbose('Searching for query', query); + if(module.has.minCharacters(query)) { + module.filter(query); + } + else { + module.hide(null,true); + } + }, + + select: { + firstUnfiltered: function() { + module.verbose('Selecting first non-filtered element'); + module.remove.selectedItem(); + $item + .not(selector.unselectable) + .not(selector.addition + selector.hidden) + .eq(0) + .addClass(className.selected) + ; + }, + nextAvailable: function($selected) { + $selected = $selected.eq(0); + var + $nextAvailable = $selected.nextAll(selector.item).not(selector.unselectable).eq(0), + $prevAvailable = $selected.prevAll(selector.item).not(selector.unselectable).eq(0), + hasNext = ($nextAvailable.length > 0) + ; + if(hasNext) { + module.verbose('Moving selection to', $nextAvailable); + $nextAvailable.addClass(className.selected); + } + else { + module.verbose('Moving selection to', $prevAvailable); + $prevAvailable.addClass(className.selected); + } + } + }, + + setup: { + api: function() { + var + apiSettings = { + debug : settings.debug, + urlData : { + value : module.get.value(), + query : module.get.query() + }, + on : false + } + ; + module.verbose('First request, initializing API'); + $module + .api(apiSettings) + ; + }, + layout: function() { + if( $module.is('select') ) { + module.setup.select(); + module.setup.returnedObject(); + } + if( !module.has.menu() ) { + module.create.menu(); + } + if ( module.is.selection() && module.is.clearable() && !module.has.clearItem() ) { + module.verbose('Adding clear icon'); + $clear = $('<i />') + .addClass('remove icon') + .insertBefore($text) + ; + } + if( module.is.search() && !module.has.search() ) { + module.verbose('Adding search input'); + $search = $('<input />') + .addClass(className.search) + .prop('autocomplete', 'off') + .insertBefore($text) + ; + } + if( module.is.multiple() && module.is.searchSelection() && !module.has.sizer()) { + module.create.sizer(); + } + if(settings.allowTab) { + module.set.tabbable(); + } + }, + select: function() { + var + selectValues = module.get.selectValues() + ; + module.debug('Dropdown initialized on a select', selectValues); + if( $module.is('select') ) { + $input = $module; + } + // see if select is placed correctly already + if($input.parent(selector.dropdown).length > 0) { + module.debug('UI dropdown already exists. Creating dropdown menu only'); + $module = $input.closest(selector.dropdown); + if( !module.has.menu() ) { + module.create.menu(); + } + $menu = $module.children(selector.menu); + module.setup.menu(selectValues); + } + else { + module.debug('Creating entire dropdown from select'); + $module = $('<div />') + .attr('class', $input.attr('class') ) + .addClass(className.selection) + .addClass(className.dropdown) + .html( templates.dropdown(selectValues, fields, settings.preserveHTML, settings.className) ) + .insertBefore($input) + ; + if($input.hasClass(className.multiple) && $input.prop('multiple') === false) { + module.error(error.missingMultiple); + $input.prop('multiple', true); + } + if($input.is('[multiple]')) { + module.set.multiple(); + } + if ($input.prop('disabled')) { + module.debug('Disabling dropdown'); + $module.addClass(className.disabled); + } + $input + .removeAttr('required') + .removeAttr('class') + .detach() + .prependTo($module) + ; + } + module.refresh(); + }, + menu: function(values) { + $menu.html( templates.menu(values, fields,settings.preserveHTML,settings.className)); + $item = $menu.find(selector.item); + $divider = settings.hideDividers ? $item.parent().children(selector.divider) : $(); + }, + reference: function() { + module.debug('Dropdown behavior was called on select, replacing with closest dropdown'); + // replace module reference + $module = $module.parent(selector.dropdown); + instance = $module.data(moduleNamespace); + element = $module.get(0); + module.refresh(); + module.setup.returnedObject(); + }, + returnedObject: function() { + var + $firstModules = $allModules.slice(0, elementIndex), + $lastModules = $allModules.slice(elementIndex + 1) + ; + // adjust all modules to use correct reference + $allModules = $firstModules.add($module).add($lastModules); + } + }, + + refresh: function() { + module.refreshSelectors(); + module.refreshData(); + }, + + refreshItems: function() { + $item = $menu.find(selector.item); + $divider = settings.hideDividers ? $item.parent().children(selector.divider) : $(); + }, + + refreshSelectors: function() { + module.verbose('Refreshing selector cache'); + $text = $module.find(selector.text); + $search = $module.find(selector.search); + $input = $module.find(selector.input); + $icon = $module.find(selector.icon); + $combo = ($module.prev().find(selector.text).length > 0) + ? $module.prev().find(selector.text) + : $module.prev() + ; + $menu = $module.children(selector.menu); + $item = $menu.find(selector.item); + $divider = settings.hideDividers ? $item.parent().children(selector.divider) : $(); + }, + + refreshData: function() { + module.verbose('Refreshing cached metadata'); + $item + .removeData(metadata.text) + .removeData(metadata.value) + ; + }, + + clearData: function() { + module.verbose('Clearing metadata'); + $item + .removeData(metadata.text) + .removeData(metadata.value) + ; + $module + .removeData(metadata.defaultText) + .removeData(metadata.defaultValue) + .removeData(metadata.placeholderText) + ; + }, + + toggle: function() { + module.verbose('Toggling menu visibility'); + if( !module.is.active() ) { + module.show(); + } + else { + module.hide(); + } + }, + + show: function(callback, preventFocus) { + callback = $.isFunction(callback) + ? callback + : function(){} + ; + if(!module.can.show() && module.is.remote()) { + module.debug('No API results retrieved, searching before show'); + module.queryRemote(module.get.query(), module.show); + } + if( module.can.show() && !module.is.active() ) { + module.debug('Showing dropdown'); + if(module.has.message() && !(module.has.maxSelections() || module.has.allResultsFiltered()) ) { + module.remove.message(); + } + if(module.is.allFiltered()) { + return true; + } + if(settings.onShow.call(element) !== false) { + module.animate.show(function() { + if( module.can.click() ) { + module.bind.intent(); + } + if(module.has.search() && !preventFocus) { + module.focusSearch(); + } + module.set.visible(); + callback.call(element); + }); + } + } + }, + + hide: function(callback, preventBlur) { + callback = $.isFunction(callback) + ? callback + : function(){} + ; + if( module.is.active() && !module.is.animatingOutward() ) { + module.debug('Hiding dropdown'); + if(settings.onHide.call(element) !== false) { + module.animate.hide(function() { + module.remove.visible(); + // hidding search focus + if ( module.is.focusedOnSearch() && preventBlur !== true ) { + $search.blur(); + } + callback.call(element); + }); + } + } else if( module.can.click() ) { + module.unbind.intent(); + } + iconClicked = false; + }, + + hideOthers: function() { + module.verbose('Finding other dropdowns to hide'); + $allModules + .not($module) + .has(selector.menu + '.' + className.visible) + .dropdown('hide') + ; + }, + + hideMenu: function() { + module.verbose('Hiding menu instantaneously'); + module.remove.active(); + module.remove.visible(); + $menu.transition('hide'); + }, + + hideSubMenus: function() { + var + $subMenus = $menu.children(selector.item).find(selector.menu) + ; + module.verbose('Hiding sub menus', $subMenus); + $subMenus.transition('hide'); + }, + + bind: { + events: function() { + module.bind.keyboardEvents(); + module.bind.inputEvents(); + module.bind.mouseEvents(); + }, + keyboardEvents: function() { + module.verbose('Binding keyboard events'); + $module + .on('keydown' + eventNamespace, module.event.keydown) + ; + if( module.has.search() ) { + $module + .on(module.get.inputEvent() + eventNamespace, selector.search, module.event.input) + ; + } + if( module.is.multiple() ) { + $document + .on('keydown' + elementNamespace, module.event.document.keydown) + ; + } + }, + inputEvents: function() { + module.verbose('Binding input change events'); + $module + .on('change' + eventNamespace, selector.input, module.event.change) + ; + }, + mouseEvents: function() { + module.verbose('Binding mouse events'); + if(module.is.multiple()) { + $module + .on(clickEvent + eventNamespace, selector.label, module.event.label.click) + .on(clickEvent + eventNamespace, selector.remove, module.event.remove.click) + ; + } + if( module.is.searchSelection() ) { + $module + .on('mousedown' + eventNamespace, module.event.mousedown) + .on('mouseup' + eventNamespace, module.event.mouseup) + .on('mousedown' + eventNamespace, selector.menu, module.event.menu.mousedown) + .on('mouseup' + eventNamespace, selector.menu, module.event.menu.mouseup) + .on(clickEvent + eventNamespace, selector.icon, module.event.icon.click) + .on(clickEvent + eventNamespace, selector.clearIcon, module.event.clearIcon.click) + .on('focus' + eventNamespace, selector.search, module.event.search.focus) + .on(clickEvent + eventNamespace, selector.search, module.event.search.focus) + .on('blur' + eventNamespace, selector.search, module.event.search.blur) + .on(clickEvent + eventNamespace, selector.text, module.event.text.focus) + ; + if(module.is.multiple()) { + $module + .on(clickEvent + eventNamespace, module.event.click) + ; + } + } + else { + if(settings.on == 'click') { + $module + .on(clickEvent + eventNamespace, selector.icon, module.event.icon.click) + .on(clickEvent + eventNamespace, module.event.test.toggle) + ; + } + else if(settings.on == 'hover') { + $module + .on('mouseenter' + eventNamespace, module.delay.show) + .on('mouseleave' + eventNamespace, module.delay.hide) + ; + } + else { + $module + .on(settings.on + eventNamespace, module.toggle) + ; + } + $module + .on('mousedown' + eventNamespace, module.event.mousedown) + .on('mouseup' + eventNamespace, module.event.mouseup) + .on('focus' + eventNamespace, module.event.focus) + .on(clickEvent + eventNamespace, selector.clearIcon, module.event.clearIcon.click) + ; + if(module.has.menuSearch() ) { + $module + .on('blur' + eventNamespace, selector.search, module.event.search.blur) + ; + } + else { + $module + .on('blur' + eventNamespace, module.event.blur) + ; + } + } + $menu + .on((hasTouch ? 'touchstart' : 'mouseenter') + eventNamespace, selector.item, module.event.item.mouseenter) + .on('mouseleave' + eventNamespace, selector.item, module.event.item.mouseleave) + .on('click' + eventNamespace, selector.item, module.event.item.click) + ; + }, + intent: function() { + module.verbose('Binding hide intent event to document'); + if(hasTouch) { + $document + .on('touchstart' + elementNamespace, module.event.test.touch) + .on('touchmove' + elementNamespace, module.event.test.touch) + ; + } + $document + .on(clickEvent + elementNamespace, module.event.test.hide) + ; + } + }, + + unbind: { + intent: function() { + module.verbose('Removing hide intent event from document'); + if(hasTouch) { + $document + .off('touchstart' + elementNamespace) + .off('touchmove' + elementNamespace) + ; + } + $document + .off(clickEvent + elementNamespace) + ; + } + }, + + filter: function(query) { + var + searchTerm = (query !== undefined) + ? query + : module.get.query(), + afterFiltered = function() { + if(module.is.multiple()) { + module.filterActive(); + } + if(query || (!query && module.get.activeItem().length == 0)) { + module.select.firstUnfiltered(); + } + if( module.has.allResultsFiltered() ) { + if( settings.onNoResults.call(element, searchTerm) ) { + if(settings.allowAdditions) { + if(settings.hideAdditions) { + module.verbose('User addition with no menu, setting empty style'); + module.set.empty(); + module.hideMenu(); + } + } + else { + module.verbose('All items filtered, showing message', searchTerm); + module.add.message(message.noResults); + } + } + else { + module.verbose('All items filtered, hiding dropdown', searchTerm); + module.hideMenu(); + } + } + else { + module.remove.empty(); + module.remove.message(); + } + if(settings.allowAdditions) { + module.add.userSuggestion(module.escape.htmlEntities(query)); + } + if(module.is.searchSelection() && module.can.show() && module.is.focusedOnSearch() ) { + module.show(); + } + } + ; + if(settings.useLabels && module.has.maxSelections()) { + return; + } + if(settings.apiSettings) { + if( module.can.useAPI() ) { + module.queryRemote(searchTerm, function() { + if(settings.filterRemoteData) { + module.filterItems(searchTerm); + } + var preSelected = $input.val(); + if(!Array.isArray(preSelected)) { + preSelected = preSelected && preSelected!=="" ? preSelected.split(settings.delimiter) : []; + } + $.each(preSelected,function(index,value){ + $item.filter('[data-value="'+value+'"]') + .addClass(className.filtered) + ; + }); + afterFiltered(); + }); + } + else { + module.error(error.noAPI); + } + } + else { + module.filterItems(searchTerm); + afterFiltered(); + } + }, + + queryRemote: function(query, callback) { + var + apiSettings = { + errorDuration : false, + cache : 'local', + throttle : settings.throttle, + urlData : { + query: query + }, + onError: function() { + module.add.message(message.serverError); + callback(); + }, + onFailure: function() { + module.add.message(message.serverError); + callback(); + }, + onSuccess : function(response) { + var + values = response[fields.remoteValues] + ; + if (!Array.isArray(values)){ + values = []; + } + module.remove.message(); + var menuConfig = {}; + menuConfig[fields.values] = values; + module.setup.menu(menuConfig); + + if(values.length===0 && !settings.allowAdditions) { + module.add.message(message.noResults); + } + callback(); + } + } + ; + if( !$module.api('get request') ) { + module.setup.api(); + } + apiSettings = $.extend(true, {}, apiSettings, settings.apiSettings); + $module + .api('setting', apiSettings) + .api('query') + ; + }, + + filterItems: function(query) { + var + searchTerm = module.remove.diacritics(query !== undefined + ? query + : module.get.query() + ), + results = null, + escapedTerm = module.escape.string(searchTerm), + regExpFlags = (settings.ignoreSearchCase ? 'i' : '') + 'gm', + beginsWithRegExp = new RegExp('^' + escapedTerm, regExpFlags) + ; + // avoid loop if we're matching nothing + if( module.has.query() ) { + results = []; + + module.verbose('Searching for matching values', searchTerm); + $item + .each(function(){ + var + $choice = $(this), + text, + value + ; + if($choice.hasClass(className.unfilterable)) { + results.push(this); + return true; + } + if(settings.match === 'both' || settings.match === 'text') { + text = module.remove.diacritics(String(module.get.choiceText($choice, false))); + if(text.search(beginsWithRegExp) !== -1) { + results.push(this); + return true; + } + else if (settings.fullTextSearch === 'exact' && module.exactSearch(searchTerm, text)) { + results.push(this); + return true; + } + else if (settings.fullTextSearch === true && module.fuzzySearch(searchTerm, text)) { + results.push(this); + return true; + } + } + if(settings.match === 'both' || settings.match === 'value') { + value = module.remove.diacritics(String(module.get.choiceValue($choice, text))); + if(value.search(beginsWithRegExp) !== -1) { + results.push(this); + return true; + } + else if (settings.fullTextSearch === 'exact' && module.exactSearch(searchTerm, value)) { + results.push(this); + return true; + } + else if (settings.fullTextSearch === true && module.fuzzySearch(searchTerm, value)) { + results.push(this); + return true; + } + } + }) + ; + } + module.debug('Showing only matched items', searchTerm); + module.remove.filteredItem(); + if(results) { + $item + .not(results) + .addClass(className.filtered) + ; + } + + if(!module.has.query()) { + $divider + .removeClass(className.hidden); + } else if(settings.hideDividers === true) { + $divider + .addClass(className.hidden); + } else if(settings.hideDividers === 'empty') { + $divider + .removeClass(className.hidden) + .filter(function() { + // First find the last divider in this divider group + // Dividers which are direct siblings are considered a group + var lastDivider = $(this).nextUntil(selector.item); + + return (lastDivider.length ? lastDivider : $(this)) + // Count all non-filtered items until the next divider (or end of the dropdown) + .nextUntil(selector.divider) + .filter(selector.item + ":not(." + className.filtered + ")") + // Hide divider if no items are found + .length === 0; + }) + .addClass(className.hidden); + } + }, + + fuzzySearch: function(query, term) { + var + termLength = term.length, + queryLength = query.length + ; + query = (settings.ignoreSearchCase ? query.toLowerCase() : query); + term = (settings.ignoreSearchCase ? term.toLowerCase() : term); + if(queryLength > termLength) { + return false; + } + if(queryLength === termLength) { + return (query === term); + } + search: for (var characterIndex = 0, nextCharacterIndex = 0; characterIndex < queryLength; characterIndex++) { + var + queryCharacter = query.charCodeAt(characterIndex) + ; + while(nextCharacterIndex < termLength) { + if(term.charCodeAt(nextCharacterIndex++) === queryCharacter) { + continue search; + } + } + return false; + } + return true; + }, + exactSearch: function (query, term) { + query = (settings.ignoreSearchCase ? query.toLowerCase() : query); + term = (settings.ignoreSearchCase ? term.toLowerCase() : term); + return term.indexOf(query) > -1; + + }, + filterActive: function() { + if(settings.useLabels) { + $item.filter('.' + className.active) + .addClass(className.filtered) + ; + } + }, + + focusSearch: function(skipHandler) { + if( module.has.search() && !module.is.focusedOnSearch() ) { + if(skipHandler) { + $module.off('focus' + eventNamespace, selector.search); + $search.focus(); + $module.on('focus' + eventNamespace, selector.search, module.event.search.focus); + } + else { + $search.focus(); + } + } + }, + + blurSearch: function() { + if( module.has.search() ) { + $search.blur(); + } + }, + + forceSelection: function() { + var + $currentlySelected = $item.not(className.filtered).filter('.' + className.selected).eq(0), + $activeItem = $item.not(className.filtered).filter('.' + className.active).eq(0), + $selectedItem = ($currentlySelected.length > 0) + ? $currentlySelected + : $activeItem, + hasSelected = ($selectedItem.length > 0) + ; + if(settings.allowAdditions || (hasSelected && !module.is.multiple())) { + module.debug('Forcing partial selection to selected item', $selectedItem); + module.event.item.click.call($selectedItem, {}, true); + } + else { + module.remove.searchTerm(); + } + }, + + change: { + values: function(values) { + if(!settings.allowAdditions) { + module.clear(); + } + module.debug('Creating dropdown with specified values', values); + var menuConfig = {}; + menuConfig[fields.values] = values; + module.setup.menu(menuConfig); + $.each(values, function(index, item) { + if(item.selected == true) { + module.debug('Setting initial selection to', item[fields.value]); + module.set.selected(item[fields.value]); + if(!module.is.multiple()) { + return false; + } + } + }); + + if(module.has.selectInput()) { + module.disconnect.selectObserver(); + $input.html(''); + $input.append('<option disabled selected value></option>'); + $.each(values, function(index, item) { + var + value = settings.templates.deQuote(item[fields.value]), + name = settings.templates.escape( + item[fields.name] || '', + settings.preserveHTML + ) + ; + $input.append('<option value="' + value + '">' + name + '</option>'); + }); + module.observe.select(); + } + } + }, + + event: { + change: function() { + if(!internalChange) { + module.debug('Input changed, updating selection'); + module.set.selected(); + } + }, + focus: function() { + if(settings.showOnFocus && !activated && module.is.hidden() && !pageLostFocus) { + module.show(); + } + }, + blur: function(event) { + pageLostFocus = (document.activeElement === this); + if(!activated && !pageLostFocus) { + module.remove.activeLabel(); + module.hide(); + } + }, + mousedown: function() { + if(module.is.searchSelection()) { + // prevent menu hiding on immediate re-focus + willRefocus = true; + } + else { + // prevents focus callback from occurring on mousedown + activated = true; + } + }, + mouseup: function() { + if(module.is.searchSelection()) { + // prevent menu hiding on immediate re-focus + willRefocus = false; + } + else { + activated = false; + } + }, + click: function(event) { + var + $target = $(event.target) + ; + // focus search + if($target.is($module)) { + if(!module.is.focusedOnSearch()) { + module.focusSearch(); + } + else { + module.show(); + } + } + }, + search: { + focus: function(event) { + activated = true; + if(module.is.multiple()) { + module.remove.activeLabel(); + } + if(settings.showOnFocus || (event.type !== 'focus' && event.type !== 'focusin')) { + module.search(); + } + }, + blur: function(event) { + pageLostFocus = (document.activeElement === this); + if(module.is.searchSelection() && !willRefocus) { + if(!itemActivated && !pageLostFocus) { + if(settings.forceSelection) { + module.forceSelection(); + } else if(!settings.allowAdditions){ + module.remove.searchTerm(); + } + module.hide(); + } + } + willRefocus = false; + } + }, + clearIcon: { + click: function(event) { + module.clear(); + if(module.is.searchSelection()) { + module.remove.searchTerm(); + } + module.hide(); + event.stopPropagation(); + } + }, + icon: { + click: function(event) { + iconClicked=true; + if(module.has.search()) { + if(!module.is.active()) { + if(settings.showOnFocus){ + module.focusSearch(); + } else { + module.toggle(); + } + } else { + module.blurSearch(); + } + } else { + module.toggle(); + } + } + }, + text: { + focus: function(event) { + activated = true; + module.focusSearch(); + } + }, + input: function(event) { + if(module.is.multiple() || module.is.searchSelection()) { + module.set.filtered(); + } + clearTimeout(module.timer); + module.timer = setTimeout(module.search, settings.delay.search); + }, + label: { + click: function(event) { + var + $label = $(this), + $labels = $module.find(selector.label), + $activeLabels = $labels.filter('.' + className.active), + $nextActive = $label.nextAll('.' + className.active), + $prevActive = $label.prevAll('.' + className.active), + $range = ($nextActive.length > 0) + ? $label.nextUntil($nextActive).add($activeLabels).add($label) + : $label.prevUntil($prevActive).add($activeLabels).add($label) + ; + if(event.shiftKey) { + $activeLabels.removeClass(className.active); + $range.addClass(className.active); + } + else if(event.ctrlKey) { + $label.toggleClass(className.active); + } + else { + $activeLabels.removeClass(className.active); + $label.addClass(className.active); + } + settings.onLabelSelect.apply(this, $labels.filter('.' + className.active)); + } + }, + remove: { + click: function() { + var + $label = $(this).parent() + ; + if( $label.hasClass(className.active) ) { + // remove all selected labels + module.remove.activeLabels(); + } + else { + // remove this label only + module.remove.activeLabels( $label ); + } + } + }, + test: { + toggle: function(event) { + var + toggleBehavior = (module.is.multiple()) + ? module.show + : module.toggle + ; + if(module.is.bubbledLabelClick(event) || module.is.bubbledIconClick(event)) { + return; + } + if( module.determine.eventOnElement(event, toggleBehavior) ) { + event.preventDefault(); + } + }, + touch: function(event) { + module.determine.eventOnElement(event, function() { + if(event.type == 'touchstart') { + module.timer = setTimeout(function() { + module.hide(); + }, settings.delay.touch); + } + else if(event.type == 'touchmove') { + clearTimeout(module.timer); + } + }); + event.stopPropagation(); + }, + hide: function(event) { + if(module.determine.eventInModule(event, module.hide)){ + if(element.id && $(event.target).attr('for') === element.id){ + event.preventDefault(); + } + } + } + }, + class: { + mutation: function(mutations) { + mutations.forEach(function(mutation) { + if(mutation.attributeName === "class") { + module.check.disabled(); + } + }); + } + }, + select: { + mutation: function(mutations) { + module.debug('<select> modified, recreating menu'); + if(module.is.selectMutation(mutations)) { + module.disconnect.selectObserver(); + module.refresh(); + module.setup.select(); + module.set.selected(); + module.observe.select(); + } + } + }, + menu: { + mutation: function(mutations) { + var + mutation = mutations[0], + $addedNode = mutation.addedNodes + ? $(mutation.addedNodes[0]) + : $(false), + $removedNode = mutation.removedNodes + ? $(mutation.removedNodes[0]) + : $(false), + $changedNodes = $addedNode.add($removedNode), + isUserAddition = $changedNodes.is(selector.addition) || $changedNodes.closest(selector.addition).length > 0, + isMessage = $changedNodes.is(selector.message) || $changedNodes.closest(selector.message).length > 0 + ; + if(isUserAddition || isMessage) { + module.debug('Updating item selector cache'); + module.refreshItems(); + } + else { + module.debug('Menu modified, updating selector cache'); + module.refresh(); + } + }, + mousedown: function() { + itemActivated = true; + }, + mouseup: function() { + itemActivated = false; + } + }, + item: { + mouseenter: function(event) { + var + $target = $(event.target), + $item = $(this), + $subMenu = $item.children(selector.menu), + $otherMenus = $item.siblings(selector.item).children(selector.menu), + hasSubMenu = ($subMenu.length > 0), + isBubbledEvent = ($subMenu.find($target).length > 0) + ; + if( !isBubbledEvent && hasSubMenu ) { + clearTimeout(module.itemTimer); + module.itemTimer = setTimeout(function() { + module.verbose('Showing sub-menu', $subMenu); + $.each($otherMenus, function() { + module.animate.hide(false, $(this)); + }); + module.animate.show(false, $subMenu); + }, settings.delay.show); + event.preventDefault(); + } + }, + mouseleave: function(event) { + var + $subMenu = $(this).children(selector.menu) + ; + if($subMenu.length > 0) { + clearTimeout(module.itemTimer); + module.itemTimer = setTimeout(function() { + module.verbose('Hiding sub-menu', $subMenu); + module.animate.hide(false, $subMenu); + }, settings.delay.hide); + } + }, + click: function (event, skipRefocus) { + var + $choice = $(this), + $target = (event) + ? $(event.target) + : $(''), + $subMenu = $choice.find(selector.menu), + text = module.get.choiceText($choice), + value = module.get.choiceValue($choice, text), + hasSubMenu = ($subMenu.length > 0), + isBubbledEvent = ($subMenu.find($target).length > 0) + ; + // prevents IE11 bug where menu receives focus even though `tabindex=-1` + if (document.activeElement.tagName.toLowerCase() !== 'input') { + $(document.activeElement).blur(); + } + if(!isBubbledEvent && (!hasSubMenu || settings.allowCategorySelection)) { + if(module.is.searchSelection()) { + if(settings.allowAdditions) { + module.remove.userAddition(); + } + module.remove.searchTerm(); + if(!module.is.focusedOnSearch() && !(skipRefocus == true)) { + module.focusSearch(true); + } + } + if(!settings.useLabels) { + module.remove.filteredItem(); + module.set.scrollPosition($choice); + } + module.determine.selectAction.call(this, text, value); + } + } + }, + + document: { + // label selection should occur even when element has no focus + keydown: function(event) { + var + pressedKey = event.which, + isShortcutKey = module.is.inObject(pressedKey, keys) + ; + if(isShortcutKey) { + var + $label = $module.find(selector.label), + $activeLabel = $label.filter('.' + className.active), + activeValue = $activeLabel.data(metadata.value), + labelIndex = $label.index($activeLabel), + labelCount = $label.length, + hasActiveLabel = ($activeLabel.length > 0), + hasMultipleActive = ($activeLabel.length > 1), + isFirstLabel = (labelIndex === 0), + isLastLabel = (labelIndex + 1 == labelCount), + isSearch = module.is.searchSelection(), + isFocusedOnSearch = module.is.focusedOnSearch(), + isFocused = module.is.focused(), + caretAtStart = (isFocusedOnSearch && module.get.caretPosition(false) === 0), + isSelectedSearch = (caretAtStart && module.get.caretPosition(true) !== 0), + $nextLabel + ; + if(isSearch && !hasActiveLabel && !isFocusedOnSearch) { + return; + } + + if(pressedKey == keys.leftArrow) { + // activate previous label + if((isFocused || caretAtStart) && !hasActiveLabel) { + module.verbose('Selecting previous label'); + $label.last().addClass(className.active); + } + else if(hasActiveLabel) { + if(!event.shiftKey) { + module.verbose('Selecting previous label'); + $label.removeClass(className.active); + } + else { + module.verbose('Adding previous label to selection'); + } + if(isFirstLabel && !hasMultipleActive) { + $activeLabel.addClass(className.active); + } + else { + $activeLabel.prev(selector.siblingLabel) + .addClass(className.active) + .end() + ; + } + event.preventDefault(); + } + } + else if(pressedKey == keys.rightArrow) { + // activate first label + if(isFocused && !hasActiveLabel) { + $label.first().addClass(className.active); + } + // activate next label + if(hasActiveLabel) { + if(!event.shiftKey) { + module.verbose('Selecting next label'); + $label.removeClass(className.active); + } + else { + module.verbose('Adding next label to selection'); + } + if(isLastLabel) { + if(isSearch) { + if(!isFocusedOnSearch) { + module.focusSearch(); + } + else { + $label.removeClass(className.active); + } + } + else if(hasMultipleActive) { + $activeLabel.next(selector.siblingLabel).addClass(className.active); + } + else { + $activeLabel.addClass(className.active); + } + } + else { + $activeLabel.next(selector.siblingLabel).addClass(className.active); + } + event.preventDefault(); + } + } + else if(pressedKey == keys.deleteKey || pressedKey == keys.backspace) { + if(hasActiveLabel) { + module.verbose('Removing active labels'); + if(isLastLabel) { + if(isSearch && !isFocusedOnSearch) { + module.focusSearch(); + } + } + $activeLabel.last().next(selector.siblingLabel).addClass(className.active); + module.remove.activeLabels($activeLabel); + event.preventDefault(); + } + else if(caretAtStart && !isSelectedSearch && !hasActiveLabel && pressedKey == keys.backspace) { + module.verbose('Removing last label on input backspace'); + $activeLabel = $label.last().addClass(className.active); + module.remove.activeLabels($activeLabel); + } + } + else { + $activeLabel.removeClass(className.active); + } + } + } + }, + + keydown: function(event) { + var + pressedKey = event.which, + isShortcutKey = module.is.inObject(pressedKey, keys) + ; + if(isShortcutKey) { + var + $currentlySelected = $item.not(selector.unselectable).filter('.' + className.selected).eq(0), + $activeItem = $menu.children('.' + className.active).eq(0), + $selectedItem = ($currentlySelected.length > 0) + ? $currentlySelected + : $activeItem, + $visibleItems = ($selectedItem.length > 0) + ? $selectedItem.siblings(':not(.' + className.filtered +')').addBack() + : $menu.children(':not(.' + className.filtered +')'), + $subMenu = $selectedItem.children(selector.menu), + $parentMenu = $selectedItem.closest(selector.menu), + inVisibleMenu = ($parentMenu.hasClass(className.visible) || $parentMenu.hasClass(className.animating) || $parentMenu.parent(selector.menu).length > 0), + hasSubMenu = ($subMenu.length> 0), + hasSelectedItem = ($selectedItem.length > 0), + selectedIsSelectable = ($selectedItem.not(selector.unselectable).length > 0), + delimiterPressed = (pressedKey == keys.delimiter && settings.allowAdditions && module.is.multiple()), + isAdditionWithoutMenu = (settings.allowAdditions && settings.hideAdditions && (pressedKey == keys.enter || delimiterPressed) && selectedIsSelectable), + $nextItem, + isSubMenuItem, + newIndex + ; + // allow selection with menu closed + if(isAdditionWithoutMenu) { + module.verbose('Selecting item from keyboard shortcut', $selectedItem); + module.event.item.click.call($selectedItem, event); + if(module.is.searchSelection()) { + module.remove.searchTerm(); + } + if(module.is.multiple()){ + event.preventDefault(); + } + } + + // visible menu keyboard shortcuts + if( module.is.visible() ) { + + // enter (select or open sub-menu) + if(pressedKey == keys.enter || delimiterPressed) { + if(pressedKey == keys.enter && hasSelectedItem && hasSubMenu && !settings.allowCategorySelection) { + module.verbose('Pressed enter on unselectable category, opening sub menu'); + pressedKey = keys.rightArrow; + } + else if(selectedIsSelectable) { + module.verbose('Selecting item from keyboard shortcut', $selectedItem); + module.event.item.click.call($selectedItem, event); + if(module.is.searchSelection()) { + module.remove.searchTerm(); + if(module.is.multiple()) { + $search.focus(); + } + } + } + event.preventDefault(); + } + + // sub-menu actions + if(hasSelectedItem) { + + if(pressedKey == keys.leftArrow) { + + isSubMenuItem = ($parentMenu[0] !== $menu[0]); + + if(isSubMenuItem) { + module.verbose('Left key pressed, closing sub-menu'); + module.animate.hide(false, $parentMenu); + $selectedItem + .removeClass(className.selected) + ; + $parentMenu + .closest(selector.item) + .addClass(className.selected) + ; + event.preventDefault(); + } + } + + // right arrow (show sub-menu) + if(pressedKey == keys.rightArrow) { + if(hasSubMenu) { + module.verbose('Right key pressed, opening sub-menu'); + module.animate.show(false, $subMenu); + $selectedItem + .removeClass(className.selected) + ; + $subMenu + .find(selector.item).eq(0) + .addClass(className.selected) + ; + event.preventDefault(); + } + } + } + + // up arrow (traverse menu up) + if(pressedKey == keys.upArrow) { + $nextItem = (hasSelectedItem && inVisibleMenu) + ? $selectedItem.prevAll(selector.item + ':not(' + selector.unselectable + ')').eq(0) + : $item.eq(0) + ; + if($visibleItems.index( $nextItem ) < 0) { + module.verbose('Up key pressed but reached top of current menu'); + event.preventDefault(); + return; + } + else { + module.verbose('Up key pressed, changing active item'); + $selectedItem + .removeClass(className.selected) + ; + $nextItem + .addClass(className.selected) + ; + module.set.scrollPosition($nextItem); + if(settings.selectOnKeydown && module.is.single()) { + module.set.selectedItem($nextItem); + } + } + event.preventDefault(); + } + + // down arrow (traverse menu down) + if(pressedKey == keys.downArrow) { + $nextItem = (hasSelectedItem && inVisibleMenu) + ? $nextItem = $selectedItem.nextAll(selector.item + ':not(' + selector.unselectable + ')').eq(0) + : $item.eq(0) + ; + if($nextItem.length === 0) { + module.verbose('Down key pressed but reached bottom of current menu'); + event.preventDefault(); + return; + } + else { + module.verbose('Down key pressed, changing active item'); + $item + .removeClass(className.selected) + ; + $nextItem + .addClass(className.selected) + ; + module.set.scrollPosition($nextItem); + if(settings.selectOnKeydown && module.is.single()) { + module.set.selectedItem($nextItem); + } + } + event.preventDefault(); + } + + // page down (show next page) + if(pressedKey == keys.pageUp) { + module.scrollPage('up'); + event.preventDefault(); + } + if(pressedKey == keys.pageDown) { + module.scrollPage('down'); + event.preventDefault(); + } + + // escape (close menu) + if(pressedKey == keys.escape) { + module.verbose('Escape key pressed, closing dropdown'); + module.hide(); + } + + } + else { + // delimiter key + if(delimiterPressed) { + event.preventDefault(); + } + // down arrow (open menu) + if(pressedKey == keys.downArrow && !module.is.visible()) { + module.verbose('Down key pressed, showing dropdown'); + module.show(); + event.preventDefault(); + } + } + } + else { + if( !module.has.search() ) { + module.set.selectedLetter( String.fromCharCode(pressedKey) ); + } + } + } + }, + + trigger: { + change: function() { + var + inputElement = $input[0] + ; + if(inputElement) { + var events = document.createEvent('HTMLEvents'); + module.verbose('Triggering native change event'); + events.initEvent('change', true, false); + inputElement.dispatchEvent(events); + } + } + }, + + determine: { + selectAction: function(text, value) { + selectActionActive = true; + module.verbose('Determining action', settings.action); + if( $.isFunction( module.action[settings.action] ) ) { + module.verbose('Triggering preset action', settings.action, text, value); + module.action[ settings.action ].call(element, text, value, this); + } + else if( $.isFunction(settings.action) ) { + module.verbose('Triggering user action', settings.action, text, value); + settings.action.call(element, text, value, this); + } + else { + module.error(error.action, settings.action); + } + selectActionActive = false; + }, + eventInModule: function(event, callback) { + var + $target = $(event.target), + inDocument = ($target.closest(document.documentElement).length > 0), + inModule = ($target.closest($module).length > 0) + ; + callback = $.isFunction(callback) + ? callback + : function(){} + ; + if(inDocument && !inModule) { + module.verbose('Triggering event', callback); + callback(); + return true; + } + else { + module.verbose('Event occurred in dropdown, canceling callback'); + return false; + } + }, + eventOnElement: function(event, callback) { + var + $target = $(event.target), + $label = $target.closest(selector.siblingLabel), + inVisibleDOM = document.body.contains(event.target), + notOnLabel = ($module.find($label).length === 0 || !(module.is.multiple() && settings.useLabels)), + notInMenu = ($target.closest($menu).length === 0) + ; + callback = $.isFunction(callback) + ? callback + : function(){} + ; + if(inVisibleDOM && notOnLabel && notInMenu) { + module.verbose('Triggering event', callback); + callback(); + return true; + } + else { + module.verbose('Event occurred in dropdown menu, canceling callback'); + return false; + } + } + }, + + action: { + + nothing: function() {}, + + activate: function(text, value, element) { + value = (value !== undefined) + ? value + : text + ; + if( module.can.activate( $(element) ) ) { + module.set.selected(value, $(element)); + if(!module.is.multiple()) { + module.hideAndClear(); + } + } + }, + + select: function(text, value, element) { + value = (value !== undefined) + ? value + : text + ; + if( module.can.activate( $(element) ) ) { + module.set.value(value, text, $(element)); + if(!module.is.multiple()) { + module.hideAndClear(); + } + } + }, + + combo: function(text, value, element) { + value = (value !== undefined) + ? value + : text + ; + module.set.selected(value, $(element)); + module.hideAndClear(); + }, + + hide: function(text, value, element) { + module.set.value(value, text, $(element)); + module.hideAndClear(); + } + + }, + + get: { + id: function() { + return id; + }, + defaultText: function() { + return $module.data(metadata.defaultText); + }, + defaultValue: function() { + return $module.data(metadata.defaultValue); + }, + placeholderText: function() { + if(settings.placeholder != 'auto' && typeof settings.placeholder == 'string') { + return settings.placeholder; + } + return $module.data(metadata.placeholderText) || ''; + }, + text: function() { + return settings.preserveHTML ? $text.html() : $text.text(); + }, + query: function() { + return String($search.val()).trim(); + }, + searchWidth: function(value) { + value = (value !== undefined) + ? value + : $search.val() + ; + $sizer.text(value); + // prevent rounding issues + return Math.ceil( $sizer.width() + 1); + }, + selectionCount: function() { + var + values = module.get.values(), + count + ; + count = ( module.is.multiple() ) + ? Array.isArray(values) + ? values.length + : 0 + : (module.get.value() !== '') + ? 1 + : 0 + ; + return count; + }, + transition: function($subMenu) { + return (settings.transition == 'auto') + ? module.is.upward($subMenu) + ? 'slide up' + : 'slide down' + : settings.transition + ; + }, + userValues: function() { + var + values = module.get.values() + ; + if(!values) { + return false; + } + values = Array.isArray(values) + ? values + : [values] + ; + return $.grep(values, function(value) { + return (module.get.item(value) === false); + }); + }, + uniqueArray: function(array) { + return $.grep(array, function (value, index) { + return $.inArray(value, array) === index; + }); + }, + caretPosition: function(returnEndPos) { + var + input = $search.get(0), + range, + rangeLength + ; + if(returnEndPos && 'selectionEnd' in input){ + return input.selectionEnd; + } + else if(!returnEndPos && 'selectionStart' in input) { + return input.selectionStart; + } + if (document.selection) { + input.focus(); + range = document.selection.createRange(); + rangeLength = range.text.length; + if(returnEndPos) { + return rangeLength; + } + range.moveStart('character', -input.value.length); + return range.text.length - rangeLength; + } + }, + value: function() { + var + value = ($input.length > 0) + ? $input.val() + : $module.data(metadata.value), + isEmptyMultiselect = (Array.isArray(value) && value.length === 1 && value[0] === '') + ; + // prevents placeholder element from being selected when multiple + return (value === undefined || isEmptyMultiselect) + ? '' + : value + ; + }, + values: function() { + var + value = module.get.value() + ; + if(value === '') { + return ''; + } + return ( !module.has.selectInput() && module.is.multiple() ) + ? (typeof value == 'string') // delimited string + ? module.escape.htmlEntities(value).split(settings.delimiter) + : '' + : value + ; + }, + remoteValues: function() { + var + values = module.get.values(), + remoteValues = false + ; + if(values) { + if(typeof values == 'string') { + values = [values]; + } + $.each(values, function(index, value) { + var + name = module.read.remoteData(value) + ; + module.verbose('Restoring value from session data', name, value); + if(name) { + if(!remoteValues) { + remoteValues = {}; + } + remoteValues[value] = name; + } + }); + } + return remoteValues; + }, + choiceText: function($choice, preserveHTML) { + preserveHTML = (preserveHTML !== undefined) + ? preserveHTML + : settings.preserveHTML + ; + if($choice) { + if($choice.find(selector.menu).length > 0) { + module.verbose('Retrieving text of element with sub-menu'); + $choice = $choice.clone(); + $choice.find(selector.menu).remove(); + $choice.find(selector.menuIcon).remove(); + } + return ($choice.data(metadata.text) !== undefined) + ? $choice.data(metadata.text) + : (preserveHTML) + ? $choice.html().trim() + : $choice.text().trim() + ; + } + }, + choiceValue: function($choice, choiceText) { + choiceText = choiceText || module.get.choiceText($choice); + if(!$choice) { + return false; + } + return ($choice.data(metadata.value) !== undefined) + ? String( $choice.data(metadata.value) ) + : (typeof choiceText === 'string') + ? String( + settings.ignoreSearchCase + ? choiceText.toLowerCase() + : choiceText + ).trim() + : String(choiceText) + ; + }, + inputEvent: function() { + var + input = $search[0] + ; + if(input) { + return (input.oninput !== undefined) + ? 'input' + : (input.onpropertychange !== undefined) + ? 'propertychange' + : 'keyup' + ; + } + return false; + }, + selectValues: function() { + var + select = {}, + oldGroup = [], + values = [] + ; + $module + .find('option') + .each(function() { + var + $option = $(this), + name = $option.html(), + disabled = $option.attr('disabled'), + value = ( $option.attr('value') !== undefined ) + ? $option.attr('value') + : name, + text = ( $option.data(metadata.text) !== undefined ) + ? $option.data(metadata.text) + : name, + group = $option.parent('optgroup') + ; + if(settings.placeholder === 'auto' && value === '') { + select.placeholder = name; + } + else { + if(group.length !== oldGroup.length || group[0] !== oldGroup[0]) { + values.push({ + type: 'header', + divider: settings.headerDivider, + name: group.attr('label') || '' + }); + oldGroup = group; + } + values.push({ + name : name, + value : value, + text : text, + disabled : disabled + }); + } + }) + ; + if(settings.placeholder && settings.placeholder !== 'auto') { + module.debug('Setting placeholder value to', settings.placeholder); + select.placeholder = settings.placeholder; + } + if(settings.sortSelect) { + if(settings.sortSelect === true) { + values.sort(function(a, b) { + return a.name.localeCompare(b.name); + }); + } else if(settings.sortSelect === 'natural') { + values.sort(function(a, b) { + return (a.name.toLowerCase().localeCompare(b.name.toLowerCase())); + }); + } else if($.isFunction(settings.sortSelect)) { + values.sort(settings.sortSelect); + } + select[fields.values] = values; + module.debug('Retrieved and sorted values from select', select); + } + else { + select[fields.values] = values; + module.debug('Retrieved values from select', select); + } + return select; + }, + activeItem: function() { + return $item.filter('.' + className.active); + }, + selectedItem: function() { + var + $selectedItem = $item.not(selector.unselectable).filter('.' + className.selected) + ; + return ($selectedItem.length > 0) + ? $selectedItem + : $item.eq(0) + ; + }, + itemWithAdditions: function(value) { + var + $items = module.get.item(value), + $userItems = module.create.userChoice(value), + hasUserItems = ($userItems && $userItems.length > 0) + ; + if(hasUserItems) { + $items = ($items.length > 0) + ? $items.add($userItems) + : $userItems + ; + } + return $items; + }, + item: function(value, strict) { + var + $selectedItem = false, + shouldSearch, + isMultiple + ; + value = (value !== undefined) + ? value + : ( module.get.values() !== undefined) + ? module.get.values() + : module.get.text() + ; + isMultiple = (module.is.multiple() && Array.isArray(value)); + shouldSearch = (isMultiple) + ? (value.length > 0) + : (value !== undefined && value !== null) + ; + strict = (value === '' || value === false || value === true) + ? true + : strict || false + ; + if(shouldSearch) { + $item + .each(function() { + var + $choice = $(this), + optionText = module.get.choiceText($choice), + optionValue = module.get.choiceValue($choice, optionText) + ; + // safe early exit + if(optionValue === null || optionValue === undefined) { + return; + } + if(isMultiple) { + if($.inArray(module.escape.htmlEntities(String(optionValue)), value.map(function(v){return String(v);})) !== -1) { + $selectedItem = ($selectedItem) + ? $selectedItem.add($choice) + : $choice + ; + } + } + else if(strict) { + module.verbose('Ambiguous dropdown value using strict type check', $choice, value); + if( optionValue === value) { + $selectedItem = $choice; + return true; + } + } + else { + if(settings.ignoreCase) { + optionValue = optionValue.toLowerCase(); + value = value.toLowerCase(); + } + if(module.escape.htmlEntities(String(optionValue)) === module.escape.htmlEntities(String(value))) { + module.verbose('Found select item by value', optionValue, value); + $selectedItem = $choice; + return true; + } + } + }) + ; + } + return $selectedItem; + } + }, + + check: { + maxSelections: function(selectionCount) { + if(settings.maxSelections) { + selectionCount = (selectionCount !== undefined) + ? selectionCount + : module.get.selectionCount() + ; + if(selectionCount >= settings.maxSelections) { + module.debug('Maximum selection count reached'); + if(settings.useLabels) { + $item.addClass(className.filtered); + module.add.message(message.maxSelections); + } + return true; + } + else { + module.verbose('No longer at maximum selection count'); + module.remove.message(); + module.remove.filteredItem(); + if(module.is.searchSelection()) { + module.filterItems(); + } + return false; + } + } + return true; + }, + disabled: function(){ + $search.attr('tabindex',module.is.disabled() ? -1 : 0); + } + }, + + restore: { + defaults: function(preventChangeTrigger) { + module.clear(preventChangeTrigger); + module.restore.defaultText(); + module.restore.defaultValue(); + }, + defaultText: function() { + var + defaultText = module.get.defaultText(), + placeholderText = module.get.placeholderText + ; + if(defaultText === placeholderText) { + module.debug('Restoring default placeholder text', defaultText); + module.set.placeholderText(defaultText); + } + else { + module.debug('Restoring default text', defaultText); + module.set.text(defaultText); + } + }, + placeholderText: function() { + module.set.placeholderText(); + }, + defaultValue: function() { + var + defaultValue = module.get.defaultValue() + ; + if(defaultValue !== undefined) { + module.debug('Restoring default value', defaultValue); + if(defaultValue !== '') { + module.set.value(defaultValue); + module.set.selected(); + } + else { + module.remove.activeItem(); + module.remove.selectedItem(); + } + } + }, + labels: function() { + if(settings.allowAdditions) { + if(!settings.useLabels) { + module.error(error.labels); + settings.useLabels = true; + } + module.debug('Restoring selected values'); + module.create.userLabels(); + } + module.check.maxSelections(); + }, + selected: function() { + module.restore.values(); + if(module.is.multiple()) { + module.debug('Restoring previously selected values and labels'); + module.restore.labels(); + } + else { + module.debug('Restoring previously selected values'); + } + }, + values: function() { + // prevents callbacks from occurring on initial load + module.set.initialLoad(); + if(settings.apiSettings && settings.saveRemoteData && module.get.remoteValues()) { + module.restore.remoteValues(); + } + else { + module.set.selected(); + } + var value = module.get.value(); + if(value && value !== '' && !(Array.isArray(value) && value.length === 0)) { + $input.removeClass(className.noselection); + } else { + $input.addClass(className.noselection); + } + module.remove.initialLoad(); + }, + remoteValues: function() { + var + values = module.get.remoteValues() + ; + module.debug('Recreating selected from session data', values); + if(values) { + if( module.is.single() ) { + $.each(values, function(value, name) { + module.set.text(name); + }); + } + else { + $.each(values, function(value, name) { + module.add.label(value, name); + }); + } + } + } + }, + + read: { + remoteData: function(value) { + var + name + ; + if(window.Storage === undefined) { + module.error(error.noStorage); + return; + } + name = sessionStorage.getItem(value); + return (name !== undefined) + ? name + : false + ; + } + }, + + save: { + defaults: function() { + module.save.defaultText(); + module.save.placeholderText(); + module.save.defaultValue(); + }, + defaultValue: function() { + var + value = module.get.value() + ; + module.verbose('Saving default value as', value); + $module.data(metadata.defaultValue, value); + }, + defaultText: function() { + var + text = module.get.text() + ; + module.verbose('Saving default text as', text); + $module.data(metadata.defaultText, text); + }, + placeholderText: function() { + var + text + ; + if(settings.placeholder !== false && $text.hasClass(className.placeholder)) { + text = module.get.text(); + module.verbose('Saving placeholder text as', text); + $module.data(metadata.placeholderText, text); + } + }, + remoteData: function(name, value) { + if(window.Storage === undefined) { + module.error(error.noStorage); + return; + } + module.verbose('Saving remote data to session storage', value, name); + sessionStorage.setItem(value, name); + } + }, + + clear: function(preventChangeTrigger) { + if(module.is.multiple() && settings.useLabels) { + module.remove.labels(); + } + else { + module.remove.activeItem(); + module.remove.selectedItem(); + module.remove.filteredItem(); + } + module.set.placeholderText(); + module.clearValue(preventChangeTrigger); + }, + + clearValue: function(preventChangeTrigger) { + module.set.value('', null, null, preventChangeTrigger); + }, + + scrollPage: function(direction, $selectedItem) { + var + $currentItem = $selectedItem || module.get.selectedItem(), + $menu = $currentItem.closest(selector.menu), + menuHeight = $menu.outerHeight(), + currentScroll = $menu.scrollTop(), + itemHeight = $item.eq(0).outerHeight(), + itemsPerPage = Math.floor(menuHeight / itemHeight), + maxScroll = $menu.prop('scrollHeight'), + newScroll = (direction == 'up') + ? currentScroll - (itemHeight * itemsPerPage) + : currentScroll + (itemHeight * itemsPerPage), + $selectableItem = $item.not(selector.unselectable), + isWithinRange, + $nextSelectedItem, + elementIndex + ; + elementIndex = (direction == 'up') + ? $selectableItem.index($currentItem) - itemsPerPage + : $selectableItem.index($currentItem) + itemsPerPage + ; + isWithinRange = (direction == 'up') + ? (elementIndex >= 0) + : (elementIndex < $selectableItem.length) + ; + $nextSelectedItem = (isWithinRange) + ? $selectableItem.eq(elementIndex) + : (direction == 'up') + ? $selectableItem.first() + : $selectableItem.last() + ; + if($nextSelectedItem.length > 0) { + module.debug('Scrolling page', direction, $nextSelectedItem); + $currentItem + .removeClass(className.selected) + ; + $nextSelectedItem + .addClass(className.selected) + ; + if(settings.selectOnKeydown && module.is.single()) { + module.set.selectedItem($nextSelectedItem); + } + $menu + .scrollTop(newScroll) + ; + } + }, + + set: { + filtered: function() { + var + isMultiple = module.is.multiple(), + isSearch = module.is.searchSelection(), + isSearchMultiple = (isMultiple && isSearch), + searchValue = (isSearch) + ? module.get.query() + : '', + hasSearchValue = (typeof searchValue === 'string' && searchValue.length > 0), + searchWidth = module.get.searchWidth(), + valueIsSet = searchValue !== '' + ; + if(isMultiple && hasSearchValue) { + module.verbose('Adjusting input width', searchWidth, settings.glyphWidth); + $search.css('width', searchWidth); + } + if(hasSearchValue || (isSearchMultiple && valueIsSet)) { + module.verbose('Hiding placeholder text'); + $text.addClass(className.filtered); + } + else if(!isMultiple || (isSearchMultiple && !valueIsSet)) { + module.verbose('Showing placeholder text'); + $text.removeClass(className.filtered); + } + }, + empty: function() { + $module.addClass(className.empty); + }, + loading: function() { + $module.addClass(className.loading); + }, + placeholderText: function(text) { + text = text || module.get.placeholderText(); + module.debug('Setting placeholder text', text); + module.set.text(text); + $text.addClass(className.placeholder); + }, + tabbable: function() { + if( module.is.searchSelection() ) { + module.debug('Added tabindex to searchable dropdown'); + $search + .val('') + ; + module.check.disabled(); + $menu + .attr('tabindex', -1) + ; + } + else { + module.debug('Added tabindex to dropdown'); + if( $module.attr('tabindex') === undefined) { + $module + .attr('tabindex', 0) + ; + $menu + .attr('tabindex', -1) + ; + } + } + }, + initialLoad: function() { + module.verbose('Setting initial load'); + initialLoad = true; + }, + activeItem: function($item) { + if( settings.allowAdditions && $item.filter(selector.addition).length > 0 ) { + $item.addClass(className.filtered); + } + else { + $item.addClass(className.active); + } + }, + partialSearch: function(text) { + var + length = module.get.query().length + ; + $search.val( text.substr(0, length)); + }, + scrollPosition: function($item, forceScroll) { + var + edgeTolerance = 5, + $menu, + hasActive, + offset, + itemHeight, + itemOffset, + menuOffset, + menuScroll, + menuHeight, + abovePage, + belowPage + ; + + $item = $item || module.get.selectedItem(); + $menu = $item.closest(selector.menu); + hasActive = ($item && $item.length > 0); + forceScroll = (forceScroll !== undefined) + ? forceScroll + : false + ; + if(module.get.activeItem().length === 0){ + forceScroll = false; + } + if($item && $menu.length > 0 && hasActive) { + itemOffset = $item.position().top; + + $menu.addClass(className.loading); + menuScroll = $menu.scrollTop(); + menuOffset = $menu.offset().top; + itemOffset = $item.offset().top; + offset = menuScroll - menuOffset + itemOffset; + if(!forceScroll) { + menuHeight = $menu.height(); + belowPage = menuScroll + menuHeight < (offset + edgeTolerance); + abovePage = ((offset - edgeTolerance) < menuScroll); + } + module.debug('Scrolling to active item', offset); + if(forceScroll || abovePage || belowPage) { + $menu.scrollTop(offset); + } + $menu.removeClass(className.loading); + } + }, + text: function(text) { + if(settings.action === 'combo') { + module.debug('Changing combo button text', text, $combo); + if(settings.preserveHTML) { + $combo.html(text); + } + else { + $combo.text(text); + } + } + else if(settings.action === 'activate') { + if(text !== module.get.placeholderText()) { + $text.removeClass(className.placeholder); + } + module.debug('Changing text', text, $text); + $text + .removeClass(className.filtered) + ; + if(settings.preserveHTML) { + $text.html(text); + } + else { + $text.text(text); + } + } + }, + selectedItem: function($item) { + var + value = module.get.choiceValue($item), + searchText = module.get.choiceText($item, false), + text = module.get.choiceText($item, true) + ; + module.debug('Setting user selection to item', $item); + module.remove.activeItem(); + module.set.partialSearch(searchText); + module.set.activeItem($item); + module.set.selected(value, $item); + module.set.text(text); + }, + selectedLetter: function(letter) { + var + $selectedItem = $item.filter('.' + className.selected), + alreadySelectedLetter = $selectedItem.length > 0 && module.has.firstLetter($selectedItem, letter), + $nextValue = false, + $nextItem + ; + // check next of same letter + if(alreadySelectedLetter) { + $nextItem = $selectedItem.nextAll($item).eq(0); + if( module.has.firstLetter($nextItem, letter) ) { + $nextValue = $nextItem; + } + } + // check all values + if(!$nextValue) { + $item + .each(function(){ + if(module.has.firstLetter($(this), letter)) { + $nextValue = $(this); + return false; + } + }) + ; + } + // set next value + if($nextValue) { + module.verbose('Scrolling to next value with letter', letter); + module.set.scrollPosition($nextValue); + $selectedItem.removeClass(className.selected); + $nextValue.addClass(className.selected); + if(settings.selectOnKeydown && module.is.single()) { + module.set.selectedItem($nextValue); + } + } + }, + direction: function($menu) { + if(settings.direction == 'auto') { + // reset position, remove upward if it's base menu + if (!$menu) { + module.remove.upward(); + } else if (module.is.upward($menu)) { + //we need make sure when make assertion openDownward for $menu, $menu does not have upward class + module.remove.upward($menu); + } + + if(module.can.openDownward($menu)) { + module.remove.upward($menu); + } + else { + module.set.upward($menu); + } + if(!module.is.leftward($menu) && !module.can.openRightward($menu)) { + module.set.leftward($menu); + } + } + else if(settings.direction == 'upward') { + module.set.upward($menu); + } + }, + upward: function($currentMenu) { + var $element = $currentMenu || $module; + $element.addClass(className.upward); + }, + leftward: function($currentMenu) { + var $element = $currentMenu || $menu; + $element.addClass(className.leftward); + }, + value: function(value, text, $selected, preventChangeTrigger) { + if(value !== undefined && value !== '' && !(Array.isArray(value) && value.length === 0)) { + $input.removeClass(className.noselection); + } else { + $input.addClass(className.noselection); + } + var + escapedValue = module.escape.value(value), + hasInput = ($input.length > 0), + currentValue = module.get.values(), + stringValue = (value !== undefined) + ? String(value) + : value, + newValue + ; + if(hasInput) { + if(!settings.allowReselection && stringValue == currentValue) { + module.verbose('Skipping value update already same value', value, currentValue); + if(!module.is.initialLoad()) { + return; + } + } + + if( module.is.single() && module.has.selectInput() && module.can.extendSelect() ) { + module.debug('Adding user option', value); + module.add.optionValue(value); + } + module.debug('Updating input value', escapedValue, currentValue); + internalChange = true; + $input + .val(escapedValue) + ; + if(settings.fireOnInit === false && module.is.initialLoad()) { + module.debug('Input native change event ignored on initial load'); + } + else if(preventChangeTrigger !== true) { + module.trigger.change(); + } + internalChange = false; + } + else { + module.verbose('Storing value in metadata', escapedValue, $input); + if(escapedValue !== currentValue) { + $module.data(metadata.value, stringValue); + } + } + if(settings.fireOnInit === false && module.is.initialLoad()) { + module.verbose('No callback on initial load', settings.onChange); + } + else if(preventChangeTrigger !== true) { + settings.onChange.call(element, value, text, $selected); + } + }, + active: function() { + $module + .addClass(className.active) + ; + }, + multiple: function() { + $module.addClass(className.multiple); + }, + visible: function() { + $module.addClass(className.visible); + }, + exactly: function(value, $selectedItem) { + module.debug('Setting selected to exact values'); + module.clear(); + module.set.selected(value, $selectedItem); + }, + selected: function(value, $selectedItem) { + var + isMultiple = module.is.multiple() + ; + $selectedItem = (settings.allowAdditions) + ? $selectedItem || module.get.itemWithAdditions(value) + : $selectedItem || module.get.item(value) + ; + if(!$selectedItem) { + return; + } + module.debug('Setting selected menu item to', $selectedItem); + if(module.is.multiple()) { + module.remove.searchWidth(); + } + if(module.is.single()) { + module.remove.activeItem(); + module.remove.selectedItem(); + } + else if(settings.useLabels) { + module.remove.selectedItem(); + } + // select each item + $selectedItem + .each(function() { + var + $selected = $(this), + selectedText = module.get.choiceText($selected), + selectedValue = module.get.choiceValue($selected, selectedText), + + isFiltered = $selected.hasClass(className.filtered), + isActive = $selected.hasClass(className.active), + isUserValue = $selected.hasClass(className.addition), + shouldAnimate = (isMultiple && $selectedItem.length == 1) + ; + if(isMultiple) { + if(!isActive || isUserValue) { + if(settings.apiSettings && settings.saveRemoteData) { + module.save.remoteData(selectedText, selectedValue); + } + if(settings.useLabels) { + module.add.label(selectedValue, selectedText, shouldAnimate); + module.add.value(selectedValue, selectedText, $selected); + module.set.activeItem($selected); + module.filterActive(); + module.select.nextAvailable($selectedItem); + } + else { + module.add.value(selectedValue, selectedText, $selected); + module.set.text(module.add.variables(message.count)); + module.set.activeItem($selected); + } + } + else if(!isFiltered && (settings.useLabels || selectActionActive)) { + module.debug('Selected active value, removing label'); + module.remove.selected(selectedValue); + } + } + else { + if(settings.apiSettings && settings.saveRemoteData) { + module.save.remoteData(selectedText, selectedValue); + } + module.set.text(selectedText); + module.set.value(selectedValue, selectedText, $selected); + $selected + .addClass(className.active) + .addClass(className.selected) + ; + } + }) + ; + module.remove.searchTerm(); + } + }, + + add: { + label: function(value, text, shouldAnimate) { + var + $next = module.is.searchSelection() + ? $search + : $text, + escapedValue = module.escape.value(value), + $label + ; + if(settings.ignoreCase) { + escapedValue = escapedValue.toLowerCase(); + } + $label = $('<a />') + .addClass(className.label) + .attr('data-' + metadata.value, escapedValue) + .html(templates.label(escapedValue, text, settings.preserveHTML, settings.className)) + ; + $label = settings.onLabelCreate.call($label, escapedValue, text); + + if(module.has.label(value)) { + module.debug('User selection already exists, skipping', escapedValue); + return; + } + if(settings.label.variation) { + $label.addClass(settings.label.variation); + } + if(shouldAnimate === true) { + module.debug('Animating in label', $label); + $label + .addClass(className.hidden) + .insertBefore($next) + .transition({ + animation : settings.label.transition, + debug : settings.debug, + verbose : settings.verbose, + duration : settings.label.duration + }) + ; + } + else { + module.debug('Adding selection label', $label); + $label + .insertBefore($next) + ; + } + }, + message: function(message) { + var + $message = $menu.children(selector.message), + html = settings.templates.message(module.add.variables(message)) + ; + if($message.length > 0) { + $message + .html(html) + ; + } + else { + $message = $('<div/>') + .html(html) + .addClass(className.message) + .appendTo($menu) + ; + } + }, + optionValue: function(value) { + var + escapedValue = module.escape.value(value), + $option = $input.find('option[value="' + module.escape.string(escapedValue) + '"]'), + hasOption = ($option.length > 0) + ; + if(hasOption) { + return; + } + // temporarily disconnect observer + module.disconnect.selectObserver(); + if( module.is.single() ) { + module.verbose('Removing previous user addition'); + $input.find('option.' + className.addition).remove(); + } + $('<option/>') + .prop('value', escapedValue) + .addClass(className.addition) + .html(value) + .appendTo($input) + ; + module.verbose('Adding user addition as an <option>', value); + module.observe.select(); + }, + userSuggestion: function(value) { + var + $addition = $menu.children(selector.addition), + $existingItem = module.get.item(value), + alreadyHasValue = $existingItem && $existingItem.not(selector.addition).length, + hasUserSuggestion = $addition.length > 0, + html + ; + if(settings.useLabels && module.has.maxSelections()) { + return; + } + if(value === '' || alreadyHasValue) { + $addition.remove(); + return; + } + if(hasUserSuggestion) { + $addition + .data(metadata.value, value) + .data(metadata.text, value) + .attr('data-' + metadata.value, value) + .attr('data-' + metadata.text, value) + .removeClass(className.filtered) + ; + if(!settings.hideAdditions) { + html = settings.templates.addition( module.add.variables(message.addResult, value) ); + $addition + .html(html) + ; + } + module.verbose('Replacing user suggestion with new value', $addition); + } + else { + $addition = module.create.userChoice(value); + $addition + .prependTo($menu) + ; + module.verbose('Adding item choice to menu corresponding with user choice addition', $addition); + } + if(!settings.hideAdditions || module.is.allFiltered()) { + $addition + .addClass(className.selected) + .siblings() + .removeClass(className.selected) + ; + } + module.refreshItems(); + }, + variables: function(message, term) { + var + hasCount = (message.search('{count}') !== -1), + hasMaxCount = (message.search('{maxCount}') !== -1), + hasTerm = (message.search('{term}') !== -1), + count, + query + ; + module.verbose('Adding templated variables to message', message); + if(hasCount) { + count = module.get.selectionCount(); + message = message.replace('{count}', count); + } + if(hasMaxCount) { + count = module.get.selectionCount(); + message = message.replace('{maxCount}', settings.maxSelections); + } + if(hasTerm) { + query = term || module.get.query(); + message = message.replace('{term}', query); + } + return message; + }, + value: function(addedValue, addedText, $selectedItem) { + var + currentValue = module.get.values(), + newValue + ; + if(module.has.value(addedValue)) { + module.debug('Value already selected'); + return; + } + if(addedValue === '') { + module.debug('Cannot select blank values from multiselect'); + return; + } + // extend current array + if(Array.isArray(currentValue)) { + newValue = currentValue.concat([addedValue]); + newValue = module.get.uniqueArray(newValue); + } + else { + newValue = [addedValue]; + } + // add values + if( module.has.selectInput() ) { + if(module.can.extendSelect()) { + module.debug('Adding value to select', addedValue, newValue, $input); + module.add.optionValue(addedValue); + } + } + else { + newValue = newValue.join(settings.delimiter); + module.debug('Setting hidden input to delimited value', newValue, $input); + } + + if(settings.fireOnInit === false && module.is.initialLoad()) { + module.verbose('Skipping onadd callback on initial load', settings.onAdd); + } + else { + settings.onAdd.call(element, addedValue, addedText, $selectedItem); + } + module.set.value(newValue, addedText, $selectedItem); + module.check.maxSelections(); + }, + }, + + remove: { + active: function() { + $module.removeClass(className.active); + }, + activeLabel: function() { + $module.find(selector.label).removeClass(className.active); + }, + empty: function() { + $module.removeClass(className.empty); + }, + loading: function() { + $module.removeClass(className.loading); + }, + initialLoad: function() { + initialLoad = false; + }, + upward: function($currentMenu) { + var $element = $currentMenu || $module; + $element.removeClass(className.upward); + }, + leftward: function($currentMenu) { + var $element = $currentMenu || $menu; + $element.removeClass(className.leftward); + }, + visible: function() { + $module.removeClass(className.visible); + }, + activeItem: function() { + $item.removeClass(className.active); + }, + filteredItem: function() { + if(settings.useLabels && module.has.maxSelections() ) { + return; + } + if(settings.useLabels && module.is.multiple()) { + $item.not('.' + className.active).removeClass(className.filtered); + } + else { + $item.removeClass(className.filtered); + } + if(settings.hideDividers) { + $divider.removeClass(className.hidden); + } + module.remove.empty(); + }, + optionValue: function(value) { + var + escapedValue = module.escape.value(value), + $option = $input.find('option[value="' + module.escape.string(escapedValue) + '"]'), + hasOption = ($option.length > 0) + ; + if(!hasOption || !$option.hasClass(className.addition)) { + return; + } + // temporarily disconnect observer + if(selectObserver) { + selectObserver.disconnect(); + module.verbose('Temporarily disconnecting mutation observer'); + } + $option.remove(); + module.verbose('Removing user addition as an <option>', escapedValue); + if(selectObserver) { + selectObserver.observe($input[0], { + childList : true, + subtree : true + }); + } + }, + message: function() { + $menu.children(selector.message).remove(); + }, + searchWidth: function() { + $search.css('width', ''); + }, + searchTerm: function() { + module.verbose('Cleared search term'); + $search.val(''); + module.set.filtered(); + }, + userAddition: function() { + $item.filter(selector.addition).remove(); + }, + selected: function(value, $selectedItem) { + $selectedItem = (settings.allowAdditions) + ? $selectedItem || module.get.itemWithAdditions(value) + : $selectedItem || module.get.item(value) + ; + + if(!$selectedItem) { + return false; + } + + $selectedItem + .each(function() { + var + $selected = $(this), + selectedText = module.get.choiceText($selected), + selectedValue = module.get.choiceValue($selected, selectedText) + ; + if(module.is.multiple()) { + if(settings.useLabels) { + module.remove.value(selectedValue, selectedText, $selected); + module.remove.label(selectedValue); + } + else { + module.remove.value(selectedValue, selectedText, $selected); + if(module.get.selectionCount() === 0) { + module.set.placeholderText(); + } + else { + module.set.text(module.add.variables(message.count)); + } + } + } + else { + module.remove.value(selectedValue, selectedText, $selected); + } + $selected + .removeClass(className.filtered) + .removeClass(className.active) + ; + if(settings.useLabels) { + $selected.removeClass(className.selected); + } + }) + ; + }, + selectedItem: function() { + $item.removeClass(className.selected); + }, + value: function(removedValue, removedText, $removedItem) { + var + values = module.get.values(), + newValue + ; + removedValue = module.escape.htmlEntities(removedValue); + if( module.has.selectInput() ) { + module.verbose('Input is <select> removing selected option', removedValue); + newValue = module.remove.arrayValue(removedValue, values); + module.remove.optionValue(removedValue); + } + else { + module.verbose('Removing from delimited values', removedValue); + newValue = module.remove.arrayValue(removedValue, values); + newValue = newValue.join(settings.delimiter); + } + if(settings.fireOnInit === false && module.is.initialLoad()) { + module.verbose('No callback on initial load', settings.onRemove); + } + else { + settings.onRemove.call(element, removedValue, removedText, $removedItem); + } + module.set.value(newValue, removedText, $removedItem); + module.check.maxSelections(); + }, + arrayValue: function(removedValue, values) { + if( !Array.isArray(values) ) { + values = [values]; + } + values = $.grep(values, function(value){ + return (removedValue != value); + }); + module.verbose('Removed value from delimited string', removedValue, values); + return values; + }, + label: function(value, shouldAnimate) { + var + $labels = $module.find(selector.label), + $removedLabel = $labels.filter('[data-' + metadata.value + '="' + module.escape.string(settings.ignoreCase ? value.toLowerCase() : value) +'"]') + ; + module.verbose('Removing label', $removedLabel); + $removedLabel.remove(); + }, + activeLabels: function($activeLabels) { + $activeLabels = $activeLabels || $module.find(selector.label).filter('.' + className.active); + module.verbose('Removing active label selections', $activeLabels); + module.remove.labels($activeLabels); + }, + labels: function($labels) { + $labels = $labels || $module.find(selector.label); + module.verbose('Removing labels', $labels); + $labels + .each(function(){ + var + $label = $(this), + value = $label.data(metadata.value), + stringValue = (value !== undefined) + ? String(value) + : value, + isUserValue = module.is.userValue(stringValue) + ; + if(settings.onLabelRemove.call($label, value) === false) { + module.debug('Label remove callback cancelled removal'); + return; + } + module.remove.message(); + if(isUserValue) { + module.remove.value(stringValue); + module.remove.label(stringValue); + } + else { + // selected will also remove label + module.remove.selected(stringValue); + } + }) + ; + }, + tabbable: function() { + if( module.is.searchSelection() ) { + module.debug('Searchable dropdown initialized'); + $search + .removeAttr('tabindex') + ; + $menu + .removeAttr('tabindex') + ; + } + else { + module.debug('Simple selection dropdown initialized'); + $module + .removeAttr('tabindex') + ; + $menu + .removeAttr('tabindex') + ; + } + }, + diacritics: function(text) { + return settings.ignoreDiacritics ? text.normalize('NFD').replace(/[\u0300-\u036f]/g, '') : text; + } + }, + + has: { + menuSearch: function() { + return (module.has.search() && $search.closest($menu).length > 0); + }, + clearItem: function() { + return ($clear.length > 0); + }, + search: function() { + return ($search.length > 0); + }, + sizer: function() { + return ($sizer.length > 0); + }, + selectInput: function() { + return ( $input.is('select') ); + }, + minCharacters: function(searchTerm) { + if(settings.minCharacters && !iconClicked) { + searchTerm = (searchTerm !== undefined) + ? String(searchTerm) + : String(module.get.query()) + ; + return (searchTerm.length >= settings.minCharacters); + } + iconClicked=false; + return true; + }, + firstLetter: function($item, letter) { + var + text, + firstLetter + ; + if(!$item || $item.length === 0 || typeof letter !== 'string') { + return false; + } + text = module.get.choiceText($item, false); + letter = letter.toLowerCase(); + firstLetter = String(text).charAt(0).toLowerCase(); + return (letter == firstLetter); + }, + input: function() { + return ($input.length > 0); + }, + items: function() { + return ($item.length > 0); + }, + menu: function() { + return ($menu.length > 0); + }, + message: function() { + return ($menu.children(selector.message).length !== 0); + }, + label: function(value) { + var + escapedValue = module.escape.value(value), + $labels = $module.find(selector.label) + ; + if(settings.ignoreCase) { + escapedValue = escapedValue.toLowerCase(); + } + return ($labels.filter('[data-' + metadata.value + '="' + module.escape.string(escapedValue) +'"]').length > 0); + }, + maxSelections: function() { + return (settings.maxSelections && module.get.selectionCount() >= settings.maxSelections); + }, + allResultsFiltered: function() { + var + $normalResults = $item.not(selector.addition) + ; + return ($normalResults.filter(selector.unselectable).length === $normalResults.length); + }, + userSuggestion: function() { + return ($menu.children(selector.addition).length > 0); + }, + query: function() { + return (module.get.query() !== ''); + }, + value: function(value) { + return (settings.ignoreCase) + ? module.has.valueIgnoringCase(value) + : module.has.valueMatchingCase(value) + ; + }, + valueMatchingCase: function(value) { + var + values = module.get.values(), + hasValue = Array.isArray(values) + ? values && ($.inArray(value, values) !== -1) + : (values == value) + ; + return (hasValue) + ? true + : false + ; + }, + valueIgnoringCase: function(value) { + var + values = module.get.values(), + hasValue = false + ; + if(!Array.isArray(values)) { + values = [values]; + } + $.each(values, function(index, existingValue) { + if(String(value).toLowerCase() == String(existingValue).toLowerCase()) { + hasValue = true; + return false; + } + }); + return hasValue; + } + }, + + is: { + active: function() { + return $module.hasClass(className.active); + }, + animatingInward: function() { + return $menu.transition('is inward'); + }, + animatingOutward: function() { + return $menu.transition('is outward'); + }, + bubbledLabelClick: function(event) { + return $(event.target).is('select, input') && $module.closest('label').length > 0; + }, + bubbledIconClick: function(event) { + return $(event.target).closest($icon).length > 0; + }, + alreadySetup: function() { + return ($module.is('select') && $module.parent(selector.dropdown).data(moduleNamespace) !== undefined && $module.prev().length === 0); + }, + animating: function($subMenu) { + return ($subMenu) + ? $subMenu.transition && $subMenu.transition('is animating') + : $menu.transition && $menu.transition('is animating') + ; + }, + leftward: function($subMenu) { + var $selectedMenu = $subMenu || $menu; + return $selectedMenu.hasClass(className.leftward); + }, + clearable: function() { + return ($module.hasClass(className.clearable) || settings.clearable); + }, + disabled: function() { + return $module.hasClass(className.disabled); + }, + focused: function() { + return (document.activeElement === $module[0]); + }, + focusedOnSearch: function() { + return (document.activeElement === $search[0]); + }, + allFiltered: function() { + return( (module.is.multiple() || module.has.search()) && !(settings.hideAdditions == false && module.has.userSuggestion()) && !module.has.message() && module.has.allResultsFiltered() ); + }, + hidden: function($subMenu) { + return !module.is.visible($subMenu); + }, + initialLoad: function() { + return initialLoad; + }, + inObject: function(needle, object) { + var + found = false + ; + $.each(object, function(index, property) { + if(property == needle) { + found = true; + return true; + } + }); + return found; + }, + multiple: function() { + return $module.hasClass(className.multiple); + }, + remote: function() { + return settings.apiSettings && module.can.useAPI(); + }, + single: function() { + return !module.is.multiple(); + }, + selectMutation: function(mutations) { + var + selectChanged = false + ; + $.each(mutations, function(index, mutation) { + if($(mutation.target).is('select') || $(mutation.addedNodes).is('select')) { + selectChanged = true; + return false; + } + }); + return selectChanged; + }, + search: function() { + return $module.hasClass(className.search); + }, + searchSelection: function() { + return ( module.has.search() && $search.parent(selector.dropdown).length === 1 ); + }, + selection: function() { + return $module.hasClass(className.selection); + }, + userValue: function(value) { + return ($.inArray(value, module.get.userValues()) !== -1); + }, + upward: function($menu) { + var $element = $menu || $module; + return $element.hasClass(className.upward); + }, + visible: function($subMenu) { + return ($subMenu) + ? $subMenu.hasClass(className.visible) + : $menu.hasClass(className.visible) + ; + }, + verticallyScrollableContext: function() { + var + overflowY = ($context.get(0) !== window) + ? $context.css('overflow-y') + : false + ; + return (overflowY == 'auto' || overflowY == 'scroll'); + }, + horizontallyScrollableContext: function() { + var + overflowX = ($context.get(0) !== window) + ? $context.css('overflow-X') + : false + ; + return (overflowX == 'auto' || overflowX == 'scroll'); + } + }, + + can: { + activate: function($item) { + if(settings.useLabels) { + return true; + } + if(!module.has.maxSelections()) { + return true; + } + if(module.has.maxSelections() && $item.hasClass(className.active)) { + return true; + } + return false; + }, + openDownward: function($subMenu) { + var + $currentMenu = $subMenu || $menu, + canOpenDownward = true, + onScreen = {}, + calculations + ; + $currentMenu + .addClass(className.loading) + ; + calculations = { + context: { + offset : ($context.get(0) === window) + ? { top: 0, left: 0} + : $context.offset(), + scrollTop : $context.scrollTop(), + height : $context.outerHeight() + }, + menu : { + offset: $currentMenu.offset(), + height: $currentMenu.outerHeight() + } + }; + if(module.is.verticallyScrollableContext()) { + calculations.menu.offset.top += calculations.context.scrollTop; + } + onScreen = { + above : (calculations.context.scrollTop) <= calculations.menu.offset.top - calculations.context.offset.top - calculations.menu.height, + below : (calculations.context.scrollTop + calculations.context.height) >= calculations.menu.offset.top - calculations.context.offset.top + calculations.menu.height + }; + if(onScreen.below) { + module.verbose('Dropdown can fit in context downward', onScreen); + canOpenDownward = true; + } + else if(!onScreen.below && !onScreen.above) { + module.verbose('Dropdown cannot fit in either direction, favoring downward', onScreen); + canOpenDownward = true; + } + else { + module.verbose('Dropdown cannot fit below, opening upward', onScreen); + canOpenDownward = false; + } + $currentMenu.removeClass(className.loading); + return canOpenDownward; + }, + openRightward: function($subMenu) { + var + $currentMenu = $subMenu || $menu, + canOpenRightward = true, + isOffscreenRight = false, + calculations + ; + $currentMenu + .addClass(className.loading) + ; + calculations = { + context: { + offset : ($context.get(0) === window) + ? { top: 0, left: 0} + : $context.offset(), + scrollLeft : $context.scrollLeft(), + width : $context.outerWidth() + }, + menu: { + offset : $currentMenu.offset(), + width : $currentMenu.outerWidth() + } + }; + if(module.is.horizontallyScrollableContext()) { + calculations.menu.offset.left += calculations.context.scrollLeft; + } + isOffscreenRight = (calculations.menu.offset.left - calculations.context.offset.left + calculations.menu.width >= calculations.context.scrollLeft + calculations.context.width); + if(isOffscreenRight) { + module.verbose('Dropdown cannot fit in context rightward', isOffscreenRight); + canOpenRightward = false; + } + $currentMenu.removeClass(className.loading); + return canOpenRightward; + }, + click: function() { + return (hasTouch || settings.on == 'click'); + }, + extendSelect: function() { + return settings.allowAdditions || settings.apiSettings; + }, + show: function() { + return !module.is.disabled() && (module.has.items() || module.has.message()); + }, + useAPI: function() { + return $.fn.api !== undefined; + } + }, + + animate: { + show: function(callback, $subMenu) { + var + $currentMenu = $subMenu || $menu, + start = ($subMenu) + ? function() {} + : function() { + module.hideSubMenus(); + module.hideOthers(); + module.set.active(); + }, + transition + ; + callback = $.isFunction(callback) + ? callback + : function(){} + ; + module.verbose('Doing menu show animation', $currentMenu); + module.set.direction($subMenu); + transition = module.get.transition($subMenu); + if( module.is.selection() ) { + module.set.scrollPosition(module.get.selectedItem(), true); + } + if( module.is.hidden($currentMenu) || module.is.animating($currentMenu) ) { + var displayType = $module.hasClass('column') ? 'flex' : false; + if(transition == 'none') { + start(); + $currentMenu.transition({ + displayType: displayType + }).transition('show'); + callback.call(element); + } + else if($.fn.transition !== undefined && $module.transition('is supported')) { + $currentMenu + .transition({ + animation : transition + ' in', + debug : settings.debug, + verbose : settings.verbose, + duration : settings.duration, + queue : true, + onStart : start, + displayType: displayType, + onComplete : function() { + callback.call(element); + } + }) + ; + } + else { + module.error(error.noTransition, transition); + } + } + }, + hide: function(callback, $subMenu) { + var + $currentMenu = $subMenu || $menu, + start = ($subMenu) + ? function() {} + : function() { + if( module.can.click() ) { + module.unbind.intent(); + } + module.remove.active(); + }, + transition = module.get.transition($subMenu) + ; + callback = $.isFunction(callback) + ? callback + : function(){} + ; + if( module.is.visible($currentMenu) || module.is.animating($currentMenu) ) { + module.verbose('Doing menu hide animation', $currentMenu); + + if(transition == 'none') { + start(); + $currentMenu.transition('hide'); + callback.call(element); + } + else if($.fn.transition !== undefined && $module.transition('is supported')) { + $currentMenu + .transition({ + animation : transition + ' out', + duration : settings.duration, + debug : settings.debug, + verbose : settings.verbose, + queue : false, + onStart : start, + onComplete : function() { + callback.call(element); + } + }) + ; + } + else { + module.error(error.transition); + } + } + } + }, + + hideAndClear: function() { + module.remove.searchTerm(); + if( module.has.maxSelections() ) { + return; + } + if(module.has.search()) { + module.hide(function() { + module.remove.filteredItem(); + }); + } + else { + module.hide(); + } + }, + + delay: { + show: function() { + module.verbose('Delaying show event to ensure user intent'); + clearTimeout(module.timer); + module.timer = setTimeout(module.show, settings.delay.show); + }, + hide: function() { + module.verbose('Delaying hide event to ensure user intent'); + clearTimeout(module.timer); + module.timer = setTimeout(module.hide, settings.delay.hide); + } + }, + + escape: { + value: function(value) { + var + multipleValues = Array.isArray(value), + stringValue = (typeof value === 'string'), + isUnparsable = (!stringValue && !multipleValues), + hasQuotes = (stringValue && value.search(regExp.quote) !== -1), + values = [] + ; + if(isUnparsable || !hasQuotes) { + return value; + } + module.debug('Encoding quote values for use in select', value); + if(multipleValues) { + $.each(value, function(index, value){ + values.push(value.replace(regExp.quote, '"')); + }); + return values; + } + return value.replace(regExp.quote, '"'); + }, + string: function(text) { + text = String(text); + return text.replace(regExp.escape, '\\$&'); + }, + htmlEntities: function(string) { + var + badChars = /[<>"'`]/g, + shouldEscape = /[&<>"'`]/, + escape = { + "<": "<", + ">": ">", + '"': """, + "'": "'", + "`": "`" + }, + escapedChar = function(chr) { + return escape[chr]; + } + ; + if(shouldEscape.test(string)) { + string = string.replace(/&(?![a-z0-9#]{1,6};)/, "&"); + return string.replace(badChars, escapedChar); + } + return string; + } + }, + + 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(Array.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 + : $allModules + ; +}; + +$.fn.dropdown.settings = { + + silent : false, + debug : false, + verbose : false, + performance : true, + + on : 'click', // what event should show menu action on item selection + action : 'activate', // action on item selection (nothing, activate, select, combo, hide, function(){}) + + values : false, // specify values to use for dropdown + + clearable : false, // whether the value of the dropdown can be cleared + + apiSettings : false, + selectOnKeydown : true, // Whether selection should occur automatically when keyboard shortcuts used + minCharacters : 0, // Minimum characters required to trigger API call + + filterRemoteData : false, // Whether API results should be filtered after being returned for query term + saveRemoteData : true, // Whether remote name/value pairs should be stored in sessionStorage to allow remote data to be restored on page refresh + + throttle : 200, // How long to wait after last user input to search remotely + + context : window, // Context to use when determining if on screen + direction : 'auto', // Whether dropdown should always open in one direction + keepOnScreen : true, // Whether dropdown should check whether it is on screen before showing + + match : 'both', // what to match against with search selection (both, text, or label) + fullTextSearch : false, // search anywhere in value (set to 'exact' to require exact matches) + ignoreDiacritics : false, // match results also if they contain diacritics of the same base character (for example searching for "a" will also match "á" or "â" or "à ", etc...) + hideDividers : false, // Whether to hide any divider elements (specified in selector.divider) that are sibling to any items when searched (set to true will hide all dividers, set to 'empty' will hide them when they are not followed by a visible item) + + placeholder : 'auto', // whether to convert blank <select> values to placeholder text + preserveHTML : true, // preserve html when selecting value + sortSelect : false, // sort selection on init + + forceSelection : true, // force a choice on blur with search selection + + allowAdditions : false, // whether multiple select should allow user added values + ignoreCase : false, // whether to consider case sensitivity when creating labels + ignoreSearchCase : true, // whether to consider case sensitivity when filtering items + hideAdditions : true, // whether or not to hide special message prompting a user they can enter a value + + maxSelections : false, // When set to a number limits the number of selections to this count + useLabels : true, // whether multiple select should filter currently active selections from choices + delimiter : ',', // when multiselect uses normal <input> the values will be delimited with this character + + showOnFocus : true, // show menu on focus + allowReselection : false, // whether current value should trigger callbacks when reselected + allowTab : true, // add tabindex to element + allowCategorySelection : false, // allow elements with sub-menus to be selected + + fireOnInit : false, // Whether callbacks should fire when initializing dropdown values + + transition : 'auto', // auto transition will slide down or up based on direction + duration : 200, // duration of transition + + glyphWidth : 1.037, // widest glyph width in em (W is 1.037 em) used to calculate multiselect input width + + headerDivider : true, // whether option headers should have an additional divider line underneath when converted from <select> <optgroup> + + // label settings on multi-select + label: { + transition : 'scale', + duration : 200, + variation : false + }, + + // delay before event + delay : { + hide : 300, + show : 200, + search : 20, + touch : 50 + }, + + /* Callbacks */ + onChange : function(value, text, $selected){}, + onAdd : function(value, text, $selected){}, + onRemove : function(value, text, $selected){}, + + onLabelSelect : function($selectedLabels){}, + onLabelCreate : function(value, text) { return $(this); }, + onLabelRemove : function(value) { return true; }, + onNoResults : function(searchTerm) { return true; }, + onShow : function(){}, + onHide : function(){}, + + /* Component */ + name : 'Dropdown', + namespace : 'dropdown', + + message: { + addResult : 'Add <b>{term}</b>', + count : '{count} selected', + maxSelections : 'Max {maxCount} selections', + noResults : 'No results found.', + serverError : 'There was an error contacting the server' + }, + + error : { + action : 'You called a dropdown action that was not defined', + alreadySetup : 'Once a select has been initialized behaviors must be called on the created ui dropdown', + labels : 'Allowing user additions currently requires the use of labels.', + missingMultiple : '<select> requires multiple property to be set to correctly preserve multiple values', + method : 'The method you called is not defined.', + noAPI : 'The API module is required to load resources remotely', + noStorage : 'Saving remote data requires session storage', + noTransition : 'This module requires ui transitions <https://github.com/Semantic-Org/UI-Transition>', + noNormalize : '"ignoreDiacritics" setting will be ignored. Browser does not support String().normalize(). You may consider including <https://cdn.jsdelivr.net/npm/[email protected]/lib/unorm.min.js> as a polyfill.' + }, + + regExp : { + escape : /[-[\]{}()*+?.,\\^$|#\s:=@]/g, + quote : /"/g + }, + + metadata : { + defaultText : 'defaultText', + defaultValue : 'defaultValue', + placeholderText : 'placeholder', + text : 'text', + value : 'value' + }, + + // property names for remote query + fields: { + remoteValues : 'results', // grouping for api results + values : 'values', // grouping for all dropdown values + disabled : 'disabled', // whether value should be disabled + name : 'name', // displayed dropdown text + value : 'value', // actual dropdown value + text : 'text', // displayed text when selected + type : 'type', // type of dropdown element + image : 'image', // optional image path + imageClass : 'imageClass', // optional individual class for image + icon : 'icon', // optional icon name + iconClass : 'iconClass', // optional individual class for icon (for example to use flag instead) + class : 'class', // optional individual class for item/header + divider : 'divider' // optional divider append for group headers + }, + + keys : { + backspace : 8, + delimiter : 188, // comma + deleteKey : 46, + enter : 13, + escape : 27, + pageUp : 33, + pageDown : 34, + leftArrow : 37, + upArrow : 38, + rightArrow : 39, + downArrow : 40 + }, + + selector : { + addition : '.addition', + divider : '.divider, .header', + dropdown : '.ui.dropdown', + hidden : '.hidden', + icon : '> .dropdown.icon', + input : '> input[type="hidden"], > select', + item : '.item', + label : '> .label', + remove : '> .label > .delete.icon', + siblingLabel : '.label', + menu : '.menu', + message : '.message', + menuIcon : '.dropdown.icon', + search : 'input.search, .menu > .search > input, .menu input.search', + sizer : '> span.sizer', + text : '> .text:not(.icon)', + unselectable : '.disabled, .filtered', + clearIcon : '> .remove.icon' + }, + + className : { + active : 'active', + addition : 'addition', + animating : 'animating', + disabled : 'disabled', + empty : 'empty', + dropdown : 'ui dropdown', + filtered : 'filtered', + hidden : 'hidden transition', + icon : 'icon', + image : 'image', + item : 'item', + label : 'ui label', + loading : 'loading', + menu : 'menu', + message : 'message', + multiple : 'multiple', + placeholder : 'default', + sizer : 'sizer', + search : 'search', + selected : 'selected', + selection : 'selection', + upward : 'upward', + leftward : 'left', + visible : 'visible', + clearable : 'clearable', + noselection : 'noselection', + delete : 'delete', + header : 'header', + divider : 'divider', + groupIcon : '', + unfilterable : 'unfilterable' + } + +}; + +/* Templates */ +$.fn.dropdown.settings.templates = { + deQuote: function(string) { + return String(string).replace(/"/g,""); + }, + escape: function(string, preserveHTML) { + if (preserveHTML){ + return string; + } + var + badChars = /[<>"'`]/g, + shouldEscape = /[&<>"'`]/, + escape = { + "<": "<", + ">": ">", + '"': """, + "'": "'", + "`": "`" + }, + escapedChar = function(chr) { + return escape[chr]; + } + ; + if(shouldEscape.test(string)) { + string = string.replace(/&(?![a-z0-9#]{1,6};)/, "&"); + return string.replace(badChars, escapedChar); + } + return string; + }, + // generates dropdown from select values + dropdown: function(select, fields, preserveHTML, className) { + var + placeholder = select.placeholder || false, + html = '', + escape = $.fn.dropdown.settings.templates.escape + ; + html += '<i class="dropdown icon"></i>'; + if(placeholder) { + html += '<div class="default text">' + escape(placeholder,preserveHTML) + '</div>'; + } + else { + html += '<div class="text"></div>'; + } + html += '<div class="'+className.menu+'">'; + html += $.fn.dropdown.settings.templates.menu(select, fields, preserveHTML,className); + html += '</div>'; + return html; + }, + + // generates just menu from select + menu: function(response, fields, preserveHTML, className) { + var + values = response[fields.values] || [], + html = '', + escape = $.fn.dropdown.settings.templates.escape, + deQuote = $.fn.dropdown.settings.templates.deQuote + ; + $.each(values, function(index, option) { + var + itemType = (option[fields.type]) + ? option[fields.type] + : 'item' + ; + + if( itemType === 'item' ) { + var + maybeText = (option[fields.text]) + ? ' data-text="' + deQuote(option[fields.text]) + '"' + : '', + maybeDisabled = (option[fields.disabled]) + ? className.disabled+' ' + : '' + ; + html += '<div class="'+ maybeDisabled + (option[fields.class] ? deQuote(option[fields.class]) : className.item)+'" data-value="' + deQuote(option[fields.value]) + '"' + maybeText + '>'; + if(option[fields.image]) { + html += '<img class="'+(option[fields.imageClass] ? deQuote(option[fields.imageClass]) : className.image)+'" src="' + deQuote(option[fields.image]) + '">'; + } + if(option[fields.icon]) { + html += '<i class="'+deQuote(option[fields.icon])+' '+(option[fields.iconClass] ? deQuote(option[fields.iconClass]) : className.icon)+'"></i>'; + } + html += escape(option[fields.name] || '', preserveHTML); + html += '</div>'; + } else if (itemType === 'header') { + var groupName = escape(option[fields.name] || '', preserveHTML), + groupIcon = option[fields.icon] ? deQuote(option[fields.icon]) : className.groupIcon + ; + if(groupName !== '' || groupIcon !== '') { + html += '<div class="' + (option[fields.class] ? deQuote(option[fields.class]) : className.header) + '">'; + if (groupIcon !== '') { + html += '<i class="' + groupIcon + ' ' + (option[fields.iconClass] ? deQuote(option[fields.iconClass]) : className.icon) + '"></i>'; + } + html += groupName; + html += '</div>'; + } + if(option[fields.divider]){ + html += '<div class="'+className.divider+'"></div>'; + } + } + }); + return html; + }, + + // generates label for multiselect + label: function(value, text, preserveHTML, className) { + var + escape = $.fn.dropdown.settings.templates.escape; + return escape(text,preserveHTML) + '<i class="'+className.delete+' icon"></i>'; + }, + + + // generates messages like "No results" + message: function(message) { + return message; + }, + + // generates user addition to selection menu + addition: function(choice) { + return choice; + } + +}; + +})( jQuery, window, document ); diff --git a/semantic/src/definitions/modules/dropdown.less b/semantic/src/definitions/modules/dropdown.less new file mode 100644 index 0000000..3953c20 --- /dev/null +++ b/semantic/src/definitions/modules/dropdown.less @@ -0,0 +1,1850 @@ +/*! + * # Fomantic-UI - Dropdown + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + + +/******************************* + Theme +*******************************/ + +@type : 'module'; +@element : 'dropdown'; + +@import (multiple) '../../theme.config'; + +/******************************* + Dropdown +*******************************/ + +.ui.dropdown { + cursor: pointer; + position: relative; + display: inline-block; + outline: none; + text-align: left; + transition: @transition; + user-select: none; + + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} + +/******************************* + Content +*******************************/ + +/*-------------- + Menu +---------------*/ + +.ui.dropdown .menu { + cursor: auto; + position: absolute; + display: none; + outline: none; + top: 100%; + min-width: max-content; + + margin: @menuMargin; + padding: @menuPadding; + background: @menuBackground; + + font-size: @relativeMedium; + text-shadow: none; + text-align: @menuTextAlign; + + box-shadow: @menuBoxShadow; + border: @menuBorder; + border-radius: @menuBorderRadius; + transition: @menuTransition; + z-index: @menuZIndex; + will-change: transform, opacity; +} + +.ui.dropdown .menu > * { + white-space: nowrap; +} + + +/*-------------- + Hidden Input +---------------*/ + +.ui.dropdown > input:not(.search):first-child, +.ui.dropdown > select { + display: none !important; +} + +/*-------------- + Dropdown Icon +---------------*/ + +.ui.dropdown:not(.labeled) > .dropdown.icon { + position: relative; + width: auto; + font-size: @dropdownIconSize; + margin: @dropdownIconMargin; +} +.ui.dropdown .menu > .item .dropdown.icon { + width: auto; + float: @itemDropdownIconFloat; + margin: @itemDropdownIconMargin; +} +.ui.dropdown .menu > .item .dropdown.icon + .text { + margin-right: @itemDropdownIconDistance; +} + + +/*-------------- + Text +---------------*/ + +.ui.dropdown > .text { + display: inline-block; + transition: @textTransition; +} + +/*-------------- + Menu Item +---------------*/ + +.ui.dropdown .menu > .item { + position: relative; + cursor: pointer; + display: block; + border: @itemBorder; + height: @itemHeight; + min-height: @itemMinHeight; + text-align: @itemTextAlign; + + border-top: @itemDivider; + line-height: @itemLineHeight; + font-size: @itemFontSize; + color: @itemColor; + + padding: @itemPadding !important; + text-transform: @itemTextTransform; + font-weight: @itemFontWeight; + box-shadow: @itemBoxShadow; + -webkit-touch-callout: none; +} +.ui.dropdown .menu > .item:first-child { + border-top-width: 0; +} + +.ui.dropdown .menu > .item.vertical { + display: flex; + flex-direction: column-reverse; +} + +/*-------------- + Floated Content +---------------*/ + +.ui.dropdown > .text > [class*="right floated"], +.ui.dropdown .menu .item > [class*="right floated"] { + float: right !important; + margin-right: 0 !important; + margin-left: @floatedDistance !important; +} +.ui.dropdown > .text > [class*="left floated"], +.ui.dropdown .menu .item > [class*="left floated"] { + float: left !important; + margin-left: 0 !important; + margin-right: @floatedDistance !important; +} + +.ui.dropdown .menu .item > i.icon.floated, +.ui.dropdown .menu .item > .flag.floated, +.ui.dropdown .menu .item > .image.floated, +.ui.dropdown .menu .item > img.floated { + margin-top: @itemLineHeightOffset; +} + + +/*-------------- + Menu Divider +---------------*/ + +.ui.dropdown .menu > .header { + margin: @menuHeaderMargin; + padding: @menuHeaderPadding; + font-weight: @menuHeaderFontWeight; + text-transform: @menuHeaderTextTransform; +} +.ui.dropdown .menu > .header:not(.ui) { + color: @menuHeaderColor; + font-size: @menuHeaderFontSize; +} +.ui.dropdown .menu > .divider { + border-top: @menuDividerBorder; + height: 0; + margin: @menuDividerMargin; +} +.ui.dropdown .menu > .horizontal.divider { + border-top: none; +} + +.ui.dropdown.dropdown .menu > .input { + width: auto; + display: flex; + margin: @menuInputMargin; + min-width: @menuInputMinWidth; +} +.ui.dropdown .menu > .header + .input { + margin-top: 0; +} +.ui.dropdown .menu > .input:not(.transparent) input { + padding: @menuInputPadding; +} +.ui.dropdown .menu > .input:not(.transparent) .button, +.ui.dropdown .menu > .input:not(.transparent) i.icon, +.ui.dropdown .menu > .input:not(.transparent) .label { + padding-top: @menuInputVerticalPadding; + padding-bottom: @menuInputVerticalPadding; +} + +/*----------------- + Item Description +-------------------*/ + +.ui.dropdown > .text > .description, +.ui.dropdown .menu > .item > .description { + float: @itemDescriptionFloat; + margin: @itemDescriptionMargin; + color: @itemDescriptionColor; +} + +.ui.dropdown .menu > .item.vertical > .description { + margin: 0; +} + +/*----------------- + Item Text +-------------------*/ + +.ui.dropdown .menu > .item.vertical > .text { + margin-bottom: @verticalItemMargin; +} + +/*----------------- + Message +-------------------*/ + +.ui.dropdown .menu > .message { + padding: @messagePadding; + font-weight: @messageFontWeight; +} +.ui.dropdown .menu > .message:not(.ui) { + color: @messageColor; +} + +/*-------------- + Sub Menu +---------------*/ + +.ui.dropdown .menu .menu { + top: @subMenuTop; + left: @subMenuLeft; + right: @subMenuRight; + margin: @subMenuMargin !important; + border-radius: @subMenuBorderRadius !important; + z-index: @subMenuZIndex !important; +} + +/* Hide Arrow */ +.ui.dropdown .menu .menu:after { + display: none; +} + +/*-------------- + Sub Elements +---------------*/ + +/* Icons / Flags / Labels / Image */ +.ui.dropdown > .text > i.icon, +.ui.dropdown > .text > .label, +.ui.dropdown > .text > .flag, +.ui.dropdown > .text > img, +.ui.dropdown > .text > .image { + margin-top: @textLineHeightOffset; +} +.ui.dropdown .menu > .item > i.icon, +.ui.dropdown .menu > .item > .label, +.ui.dropdown .menu > .item > .flag, +.ui.dropdown .menu > .item > .image, +.ui.dropdown .menu > .item > img { + margin-top: @itemLineHeightOffset; +} + +.ui.dropdown > .text > i.icon, +.ui.dropdown > .text > .label, +.ui.dropdown > .text > .flag, +.ui.dropdown > .text > img, +.ui.dropdown > .text > .image, +.ui.dropdown .menu > .item > i.icon, +.ui.dropdown .menu > .item > .label, +.ui.dropdown .menu > .item > .flag, +.ui.dropdown .menu > .item > .image, +.ui.dropdown .menu > .item > img { + margin-left: 0; + float: @itemElementFloat; + margin-right: @itemElementDistance; +} + +/*-------------- + Image +---------------*/ + +.ui.dropdown > .text > img, +.ui.dropdown > .text > .image:not(.icon), +.ui.dropdown .menu > .item > .image:not(.icon), +.ui.dropdown .menu > .item > img { + display: inline-block; + vertical-align: top; + width: auto; + margin-top: @menuImageVerticalMargin; + margin-bottom: @menuImageVerticalMargin; + max-height: @menuImageMaxHeight; +} + + +/******************************* + Coupling +*******************************/ + + +/*-------------- + Menu +---------------*/ + +/* Remove Menu Item Divider */ +.ui.dropdown .ui.menu > .item:before, +.ui.menu .ui.dropdown .menu > .item:before { + display: none; +} + +/* Prevent Menu Item Border */ +.ui.menu .ui.dropdown .menu .active.item { + border-left: none; +} + +/* Automatically float dropdown menu right on last menu item */ +.ui.menu .right.menu .dropdown:last-child > .menu:not(.left), +.ui.menu .right.dropdown.item > .menu:not(.left), +.ui.buttons > .ui.dropdown:last-child > .menu:not(.left) { + left: auto; + right: 0; +} + +& when (@variationDropdownLabel) { + /*-------------- + Label + ---------------*/ + + /* Dropdown Menu */ + .ui.label.dropdown .menu { + min-width: 100%; + } +} + +& when (@variationDropdownButton) { + /*-------------- + Button + ---------------*/ + + /* No Margin On Icon Button */ + .ui.dropdown.icon.button > .dropdown.icon { + margin: 0; + } + .ui.button.dropdown .menu { + min-width: 100%; + } +} + + + +/******************************* + Types +*******************************/ +select.ui.dropdown { + height: @selectHeight; + padding: @selectPadding; + border: @selectBorder; + visibility: @selectVisibility; +} + +& when (@variationDropdownSelection) { + /*-------------- + Selection + ---------------*/ + + /* Displays like a select box */ + .ui.selection.dropdown { + cursor: pointer; + word-wrap: break-word; + line-height: 1em; + white-space: normal; + outline: 0; + transform: rotateZ(0deg); + + min-width: @selectionMinWidth; + min-height: @selectionMinHeight; + + background: @selectionBackground; + display: @selectionDisplay; + padding: @selectionPadding; + color: @selectionTextColor; + box-shadow: @selectionBoxShadow; + border: @selectionBorder; + border-radius: @selectionBorderRadius; + transition: @selectionTransition; + } + .ui.selection.dropdown.visible, + .ui.selection.dropdown.active { + z-index: @selectionZIndex; + } + + .ui.selection.dropdown > .search.icon, + .ui.selection.dropdown > .delete.icon, + .ui.selection.dropdown > .dropdown.icon { + cursor: pointer; + position: absolute; + width: auto; + height: auto; + line-height: @searchSelectionLineHeight; + top: @selectionVerticalPadding; + right: @selectionHorizontalPadding; + z-index: @selectionIconZIndex; + margin: @selectionIconMargin; + padding: @selectionIconPadding; + opacity: @selectionIconOpacity; + transition: @selectionIconTransition; + } + & when (@variationDropdownCompact) { + /* Compact */ + .ui.compact.selection.dropdown { + min-width: 0; + } + } + + /* Selection Menu */ + .ui.selection.dropdown .menu { + overflow-x: hidden; + overflow-y: auto; + backface-visibility: hidden; + -webkit-overflow-scrolling: touch; + border-top-width: 0 !important; + width: auto; + outline: none; + margin: 0 -@menuBorderWidth; + min-width: @menuMinWidth; + width: @menuMinWidth; + + border-radius: @selectionMenuBorderRadius; + box-shadow: @selectionMenuBoxShadow; + transition: @selectionMenuTransition; + } + .ui.selection.dropdown .menu:after, + .ui.selection.dropdown .menu:before { + display: none; + } + + /*-------------- + Message + ---------------*/ + + .ui.selection.dropdown .menu > .message { + padding: @selectionMessagePadding; + } + + @media only screen and (max-width : @largestMobileScreen) { + & when (@variationDropdownShort) { + .ui.selection.dropdown.short .menu { + max-height: @selectionMobileMaxMenuHeight * 0.75; + } + .ui.selection.dropdown[class*="very short"] .menu { + max-height: @selectionMobileMaxMenuHeight * 0.5; + } + } + .ui.selection.dropdown .menu { + max-height: @selectionMobileMaxMenuHeight; + } + & when (@variationDropdownLong) { + .ui.selection.dropdown.long .menu { + max-height: @selectionMobileMaxMenuHeight * 2; + } + .ui.selection.dropdown[class*="very long"] .menu { + max-height: @selectionMobileMaxMenuHeight * 3; + } + } + } + @media only screen and (min-width: @tabletBreakpoint) { + & when (@variationDropdownShort) { + .ui.selection.dropdown.short .menu { + max-height: @selectionTabletMaxMenuHeight * 0.75; + } + .ui.selection.dropdown[class*="very short"] .menu { + max-height: @selectionTabletMaxMenuHeight * 0.5; + } + } + .ui.selection.dropdown .menu { + max-height: @selectionTabletMaxMenuHeight; + } + & when (@variationDropdownLong) { + .ui.selection.dropdown.long .menu { + max-height: @selectionTabletMaxMenuHeight * 2; + } + .ui.selection.dropdown[class*="very long"] .menu { + max-height: @selectionTabletMaxMenuHeight * 3; + } + } + } + @media only screen and (min-width: @computerBreakpoint) { + & when (@variationDropdownShort) { + .ui.selection.dropdown.short .menu { + max-height: @selectionComputerMaxMenuHeight * 0.75; + } + .ui.selection.dropdown[class*="very short"] .menu { + max-height: @selectionComputerMaxMenuHeight * 0.5; + } + } + .ui.selection.dropdown .menu { + max-height: @selectionComputerMaxMenuHeight; + } + & when (@variationDropdownLong) { + .ui.selection.dropdown.long .menu { + max-height: @selectionComputerMaxMenuHeight * 2; + } + .ui.selection.dropdown[class*="very long"] .menu { + max-height: @selectionComputerMaxMenuHeight * 3; + } + } + } + @media only screen and (min-width: @widescreenMonitorBreakpoint) { + & when (@variationDropdownShort) { + .ui.selection.dropdown.short .menu { + max-height: @selectionWidescreenMaxMenuHeight * 0.75; + } + .ui.selection.dropdown[class*="very short"] .menu { + max-height: @selectionWidescreenMaxMenuHeight * 0.5; + } + } + .ui.selection.dropdown .menu { + max-height: @selectionWidescreenMaxMenuHeight; + } + & when (@variationDropdownLong) { + .ui.selection.dropdown.long .menu { + max-height: @selectionWidescreenMaxMenuHeight * 2; + } + .ui.selection.dropdown[class*="very long"] .menu { + max-height: @selectionWidescreenMaxMenuHeight * 3; + } + } + } + + /* Menu Item */ + .ui.selection.dropdown .menu > .item { + border-top: @selectionItemDivider; + padding: @selectionItemPadding !important; + white-space: normal; + word-wrap: normal; + } + + /* User Item */ + .ui.selection.dropdown .menu > .hidden.addition.item { + display: none; + } + + /* Hover */ + .ui.selection.dropdown:hover { + border-color: @selectionHoverBorderColor; + box-shadow: @selectionHoverBoxShadow; + } + + /* Active */ + .ui.selection.active.dropdown { + border-color: @selectionVisibleBorderColor; + box-shadow: @selectionVisibleBoxShadow; + } + .ui.selection.active.dropdown .menu { + border-color: @selectionVisibleBorderColor; + box-shadow: @selectionVisibleMenuBoxShadow; + } + + /* Focus */ + .ui.selection.dropdown:focus { + border-color: @selectionFocusBorderColor; + box-shadow: @selectionFocusBoxShadow; + } + .ui.selection.dropdown:focus .menu { + border-color: @selectionFocusBorderColor; + box-shadow: @selectionFocusMenuBoxShadow; + } + + /* Visible */ + .ui.selection.visible.dropdown > .text:not(.default) { + font-weight: @selectionVisibleTextFontWeight; + color: @selectionVisibleTextColor; + } + + /* Visible Hover */ + .ui.selection.active.dropdown:hover { + border-color: @selectionActiveHoverBorderColor; + box-shadow: @selectionActiveHoverBoxShadow; + } + .ui.selection.active.dropdown:hover .menu { + border-color: @selectionActiveHoverBorderColor; + box-shadow: @selectionActiveHoverMenuBoxShadow; + } + + /* Dropdown Icon */ + .ui.active.selection.dropdown > .dropdown.icon, + .ui.visible.selection.dropdown > .dropdown.icon { + opacity: @selectionVisibleIconOpacity; + z-index: 3; + } + + /* Connecting Border */ + .ui.active.selection.dropdown { + border-bottom-left-radius: @selectionVisibleConnectingBorder !important; + border-bottom-right-radius: @selectionVisibleConnectingBorder !important; + } + + /* Empty Connecting Border */ + .ui.active.empty.selection.dropdown { + border-radius: @selectionBorderRadius !important; + box-shadow: @selectionBoxShadow !important; + } + .ui.active.empty.selection.dropdown .menu { + border: none !important; + box-shadow: none !important; + } + & when (@variationDropdownScrollhint) { + /* CSS specific to iOS devices or firefox mobile only */ + @supports (-webkit-touch-callout: none) or (-webkit-overflow-scrolling: touch) or (-moz-appearance:none) { + @media (-moz-touch-enabled), (pointer: coarse) { + .ui.dropdown .scrollhint.menu:not(.hidden):before { + animation: scrollhint @scrollhintDuration @scrollhintEasing @scrollhintIteration; + content: ''; + z-index: @scrollhintZIndex; + display: block; + position: absolute; + opacity: 0; + right: @scrollhintOffsetRight; + top: 0; + height: 100%; + border-right: @scrollhintRightBorder; + border-left: @scrollhintLeftBorder; + border-image: linear-gradient(to bottom, @scrollhintStartColor, @scrollhintEndColor) 1 100%; + } + + .ui.inverted.dropdown .scrollhint.menu:not(.hidden):before { + border-image: linear-gradient(to bottom, @invertedScrollhintStartColor, @invertedScrollhintEndColor) 1 100%; + } + + @keyframes scrollhint { + 0% { + opacity: 1; + top: 100%; + } + 100% { + opacity: 0; + top: 0; + } + } + } + } + } +} + +& when (@variationDropdownSearch) { + /*-------------- + Searchable + ---------------*/ + + /* Search Selection */ + .ui.search.dropdown { + min-width: @searchMinWidth; + } + + /* Search Dropdown */ + .ui.search.dropdown > input.search { + background: none transparent !important; + border: none !important; + box-shadow: none !important; + cursor: text; + top: 0; + left: @textCursorSpacing; + width: 100%; + outline: none; + -webkit-tap-highlight-color: rgba(255, 255, 255, 0); + padding: inherit; + } + + /* Text Layering */ + .ui.search.dropdown > input.search { + position: absolute; + z-index: 2; + } + .ui.search.dropdown > .text { + cursor: text; + position: relative; + left: @textCursorSpacing; + z-index: auto; + } + + & when (@variationDropdownSelection) { + /* Search Selection */ + .ui.search.selection.dropdown > input.search { + line-height: @searchSelectionLineHeight; + padding: @searchSelectionInputPadding; + } + + /* Used to size multi select input to character width */ + .ui.search.selection.dropdown > span.sizer { + line-height: @searchSelectionLineHeight; + padding: @searchSelectionInputPadding; + display: none; + white-space: pre; + } + } + + /* Active/Visible Search */ + .ui.search.dropdown.active > input.search, + .ui.search.dropdown.visible > input.search { + cursor: auto; + } + .ui.search.dropdown.active > .text, + .ui.search.dropdown.visible > .text { + pointer-events: none; + } + + /* Filtered Text */ + .ui.active.search.dropdown input.search:focus + .text i.icon, + .ui.active.search.dropdown input.search:focus + .text .flag { + opacity: @selectionTextUnderlayIconOpacity; + } + .ui.active.search.dropdown input.search:focus + .text { + color: @selectionTextUnderlayColor !important; + } + + .ui.search.dropdown.button > span.sizer { + display: none; + } + + /* Search Menu */ + .ui.search.dropdown .menu { + overflow-x: hidden; + overflow-y: auto; + backface-visibility: hidden; + -webkit-overflow-scrolling: touch; + } + @media only screen and (max-width : @largestMobileScreen) { + .ui.search.dropdown .menu { + max-height: @searchMobileMaxMenuHeight; + } + } + @media only screen and (min-width: @tabletBreakpoint) { + .ui.search.dropdown .menu { + max-height: @searchTabletMaxMenuHeight; + } + } + @media only screen and (min-width: @computerBreakpoint) { + .ui.search.dropdown .menu { + max-height: @searchComputerMaxMenuHeight; + } + } + @media only screen and (min-width: @widescreenMonitorBreakpoint) { + .ui.search.dropdown .menu { + max-height: @searchWidescreenMaxMenuHeight; + } + } +} + +/* Clearable Selection */ +.ui.dropdown > .remove.icon { + cursor: pointer; + font-size: @dropdownIconSize; + margin: @selectionIconMargin; + padding: @selectionIconPadding; + right: 3em; + top: @selectionVerticalPadding; + position: absolute; + opacity: 0.6; + z-index: @selectionIconZIndex; +} + +.ui.clearable.dropdown .text, +.ui.clearable.dropdown a:last-of-type { + margin-right: 1.5em; +} + +.ui.dropdown select.noselection ~ .remove.icon, +.ui.dropdown input[value=''] ~ .remove.icon, +.ui.dropdown input:not([value]) ~ .remove.icon, +.ui.dropdown.loading > .remove.icon { + display: none; +} + +& when (@variationDropdownMultiple) { + /*-------------- + Multiple + ---------------*/ + + /* Multiple Selection */ + .ui.ui.multiple.dropdown { + padding: @multipleSelectionPadding; + } + .ui.multiple.dropdown .menu { + cursor: auto; + } + + /* Selection Label */ + .ui.multiple.dropdown > .label { + display: inline-block; + white-space: normal; + font-size: @labelSize; + padding: @labelPadding; + margin: @labelMargin; + box-shadow: @labelBoxShadow; + } + + /* Dropdown Icon */ + .ui.multiple.dropdown .dropdown.icon { + margin: @multipleSelectionDropdownIconMargin; + padding: @multipleSelectionDropdownIconPadding; + } + + /* Text */ + .ui.multiple.dropdown > .text { + position: static; + padding: 0; + max-width: 100%; + margin: @multipleSelectionChildMargin; + line-height: @multipleSelectionChildLineHeight; + &.default { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + } + .ui.multiple.dropdown > .label ~ input.search { + margin-left: @multipleSelectionSearchAfterLabelDistance !important; + } + .ui.multiple.dropdown > .label ~ .text { + display: none; + } + .ui.multiple.dropdown > .label:not(.image) > img:not(.centered) { + margin-right: @itemElementDistance; + } + .ui.multiple.dropdown > .label:not(.image) > img.ui:not(.avatar) { + margin-bottom: @itemElementBottomDistance; + } + .ui.multiple.dropdown > .image.label img { + margin: @imageLabelImageMargin; + height: @imageLabelHeight; + } + + & when (@variationDropdownSearch) { + /*----------------- + Multiple Search + -----------------*/ + + /* Multiple Search Selection */ + .ui.multiple.search.dropdown, + .ui.multiple.search.dropdown > input.search { + cursor: text; + } + + /* Prompt Text */ + .ui.multiple.search.dropdown > .text { + display: inline-block; + position: absolute; + top: 0; + left: 0; + padding: inherit; + margin: @multipleSelectionChildMargin; + line-height: @multipleSelectionChildLineHeight; + } + + .ui.multiple.search.dropdown > .label ~ .text { + display: none; + } + + /* Search */ + .ui.multiple.search.dropdown > input.search { + position: static; + padding: 0; + max-width: 100%; + margin: @multipleSelectionChildMargin; + width: @multipleSelectionSearchStartWidth; + line-height: @multipleSelectionChildLineHeight; + } + + .ui.multiple.search.dropdown.button { + min-width: @selectionMinWidth; + } + } +} + +& when (@variationDropdownInline) { + /*-------------- + Inline + ---------------*/ + + .ui.inline.dropdown { + cursor: pointer; + display: inline-block; + color: @inlineTextColor; + } + .ui.inline.dropdown .dropdown.icon { + margin: @inlineIconMargin; + vertical-align: baseline; + } + .ui.inline.dropdown > .text { + font-weight: @inlineTextFontWeight; + } + .ui.inline.dropdown .menu { + cursor: auto; + margin-top: @inlineMenuDistance; + border-radius: @inlineMenuBorderRadius; + } +} + + +/******************************* + States +*******************************/ + + +/*-------------------- + Active +----------------------*/ + +/* Menu Item Active */ +.ui.dropdown .menu .active.item { + background: @activeItemBackground; + font-weight: @activeItemFontWeight; + color: @activeItemColor; + box-shadow: @activeItemBoxShadow; + z-index: @activeItemZIndex; +} + + +/*-------------------- + Hover +----------------------*/ + +/* Menu Item Hover */ +.ui.dropdown .menu > .item:hover { + background: @hoveredItemBackground; + color: @hoveredItemColor; + z-index: @hoveredZIndex; +} + +/*-------------------- + Default Text +----------------------*/ + +.ui.dropdown:not(.button) > .default.text, +.ui.default.dropdown:not(.button) > .text { + color: @defaultTextColor; +} +.ui.dropdown:not(.button) > input:focus ~ .default.text, +.ui.default.dropdown:not(.button) > input:focus ~ .text { + color: @defaultTextFocusColor; +} + +& when (@variationDropdownLoading) { + + /*-------------------- + Loading + ---------------------*/ + + .ui.loading.dropdown > i.icon { + height: @relative14px !important; + } + .ui.loading.selection.dropdown > i.icon { + padding: @relative21px @relative18px !important; + } + .ui.loading.dropdown > i.icon:before { + position: absolute; + content: ''; + top: 50%; + left: 50%; + + margin: @loaderMargin; + width: @loaderSize; + height: @loaderSize; + + border-radius: @circularRadius; + border: @loaderLineWidth solid @loaderFillColor; + } + .ui.loading.dropdown > i.icon:after { + position: absolute; + content: ''; + top: 50%; + left: 50%; + box-shadow: 0 0 0 1px transparent; + + margin: @loaderMargin; + width: @loaderSize; + height: @loaderSize; + + animation: loader @loaderSpeed infinite linear; + border: @loaderLineWidth solid @loaderLineColor; + border-radius: @circularRadius; + + } + + /* Coupling */ + .ui.loading.dropdown.button > i.icon:before, + .ui.loading.dropdown.button > i.icon:after { + display: none; + } + + .ui.loading.dropdown > .text { + transition: none; + } + + /* Used To Check Position */ + .ui.dropdown .loading.menu { + display: block; + visibility: hidden; + z-index: @loadingZIndex; + } + .ui.dropdown > .loading.menu { + left: 0 !important; + right: auto !important; + } + .ui.dropdown > .menu .loading.menu { + left: 100% !important; + right: auto !important; + } +} + +/*-------------------- + Keyboard Select +----------------------*/ + +/* Selected Item */ +.ui.dropdown.selected, +.ui.dropdown .menu .selected.item { + background: @selectedBackground; + color: @selectedColor; +} + + +/*-------------------- + Search Filtered +----------------------*/ + +/* Filtered Item */ +.ui.dropdown > .filtered.text { + visibility: hidden; +} +.ui.dropdown .filtered.item { + display: none !important; +} + +& when (@variationDropdownStates) { + /*-------------------- + States + ----------------------*/ + each(@formStates, { + @state: replace(@key, '@', ''); + @c: @formStates[@@state][dropdownLabelColor]; + @bdc: @formStates[@@state][borderColor]; + + .ui.dropdown.@{state}, + .ui.dropdown.@{state} > .text, + .ui.dropdown.@{state} > .default.text { + color: @c; + } + & when (@variationDropdownSelection) { + .ui.selection.dropdown.@{state} { + background: @formStates[@@state][background]; + border-color: @bdc; + } + + .ui.selection.dropdown.@{state}:hover { + border-color: @bdc; + } + + & when (@variationDropdownMultiple) { + .ui.multiple.selection.@{state}.dropdown > .label { + border-color: @bdc; + } + } + } + .ui.dropdown.@{state} > .menu, + .ui.dropdown.@{state} > .menu .menu { + border-color: @bdc; + } + .ui.dropdown.@{state} > .menu > .item { + color: @c; + } + + /* Item Hover */ + .ui.dropdown.@{state} > .menu > .item:hover { + background-color: @formStates[@@state][dropdownHoverBackground]; + } + + /* Item Active */ + .ui.dropdown.@{state} > .menu .active.item { + background-color: @formStates[@@state][dropdownActiveBackground]; + } + }) +} + +& when (@variationDropdownClear) { +/*-------------------- + Clear +----------------------*/ + + .ui.dropdown > .clear.dropdown.icon { + opacity: @clearableIconOpacity; + transition: opacity @defaultDuration @defaultEasing; + } + .ui.dropdown > .clear.dropdown.icon:hover { + opacity: @clearableIconActiveOpacity; + } +} + +& when (@variationDropdownDisabled) { + /*-------------------- + Disabled + ----------------------*/ + + /* Disabled */ + .ui.disabled.dropdown, + .ui.dropdown .menu > .disabled.item { + cursor: default; + pointer-events: none; + opacity: @disabledOpacity; + } +} + + +/******************************* + Variations +*******************************/ + +/*-------------- + Direction +---------------*/ + +/* Flyout Direction */ +.ui.dropdown .menu { + left: 0; +} + + +/* Default Side (Right) */ +.ui.dropdown .right.menu > .menu, +.ui.dropdown .menu .right.menu { + left: 100% !important; + right: auto !important; + border-radius: @subMenuBorderRadius !important; +} +& when (@variationDropdownLeft) { + /* Leftward Opening Menu */ + .ui.dropdown > .left.menu { + left: auto !important; + right: 0 !important; + } + + .ui.dropdown > .left.menu .menu, + .ui.dropdown .menu .left.menu { + left: auto; + right: 100%; + margin: @leftSubMenuMargin !important; + border-radius: @leftSubMenuBorderRadius !important; + } +} + +.ui.dropdown .item .left.dropdown.icon, +.ui.dropdown .left.menu .item .dropdown.icon { + width: auto; + float: @leftMenuDropdownIconFloat; + margin: @leftMenuDropdownIconMargin; +} +.ui.dropdown .item .left.dropdown.icon, +.ui.dropdown .left.menu .item .dropdown.icon { + width: auto; + float: @leftMenuDropdownIconFloat; + margin: @leftMenuDropdownIconMargin; +} +.ui.dropdown .item .left.dropdown.icon + .text, +.ui.dropdown .left.menu .item .dropdown.icon + .text { + margin-left: @itemDropdownIconDistance; + margin-right: 0; +} + +& when (@variationDropdownUpward) { + /*-------------- + Upward + ---------------*/ + + /* Upward Main Menu */ + .ui.upward.dropdown > .menu { + top: auto; + bottom: 100%; + box-shadow: @upwardMenuBoxShadow; + border-radius: @upwardMenuBorderRadius; + } + + /* Upward Sub Menu */ + .ui.dropdown .upward.menu { + top: auto !important; + bottom: 0 !important; + } + + /* Active Upward */ + .ui.simple.upward.active.dropdown, + .ui.simple.upward.dropdown:hover { + border-radius: @borderRadius @borderRadius 0 0 !important; + } + .ui.upward.dropdown.button:not(.pointing):not(.floating).active { + border-radius: @borderRadius @borderRadius 0 0; + } + + /* Selection */ + .ui.upward.selection.dropdown .menu { + border-top-width: @menuBorderWidth !important; + border-bottom-width: 0 !important; + box-shadow: @upwardSelectionMenuBoxShadow; + } + .ui.upward.selection.dropdown:hover { + box-shadow: @upwardSelectionHoverBoxShadow; + } + + /* Active Upward */ + .ui.active.upward.selection.dropdown { + border-radius: @upwardSelectionVisibleBorderRadius !important; + } + + /* Visible Upward */ + .ui.upward.selection.dropdown.visible { + box-shadow: @upwardSelectionVisibleBoxShadow; + border-radius: @upwardSelectionVisibleBorderRadius !important; + } + + /* Visible Hover Upward */ + .ui.upward.active.selection.dropdown:hover { + box-shadow: @upwardSelectionActiveHoverBoxShadow; + } + .ui.upward.active.selection.dropdown:hover .menu { + box-shadow: @upwardSelectionActiveHoverMenuBoxShadow; + } +} + +& when (@variationDropdownScrolling) { + /*-------------- + Scrolling + ---------------*/ + + /* Selection Menu */ + .ui.scrolling.dropdown .menu, + .ui.dropdown .scrolling.menu { + overflow-x: hidden; + overflow-y: auto; + } + + .ui.scrolling.dropdown .menu { + overflow-x: hidden; + overflow-y: auto; + backface-visibility: hidden; + -webkit-overflow-scrolling: touch; + min-width: 100% !important; + width: auto !important; + } + + .ui.dropdown .scrolling.menu { + position: static; + overflow-y: auto; + border: none; + box-shadow: none !important; + border-radius: 0 !important; + margin: 0 !important; + min-width: 100% !important; + width: auto !important; + border-top: @menuBorder; + } + .ui.scrolling.dropdown .menu .item.item.item, + .ui.dropdown .scrolling.menu > .item.item.item { + border-top: @scrollingMenuItemBorder; + } + .ui.scrolling.dropdown .menu .item:first-child, + .ui.dropdown .scrolling.menu .item:first-child { + border-top: none; + } + .ui.dropdown > .animating.menu .scrolling.menu, + .ui.dropdown > .visible.menu .scrolling.menu { + display: block; + } + + /* Scrollbar in IE */ + @media all and (-ms-high-contrast:none) { + .ui.scrolling.dropdown .menu, + .ui.dropdown .scrolling.menu { + min-width: e(%("calc(100%% - %d)", @scrollbarWidth)); + } + } + @media only screen and (max-width : @largestMobileScreen) { + .ui.scrolling.dropdown .menu, + .ui.dropdown .scrolling.menu { + max-height: @scrollingMobileMaxMenuHeight; + } + } + @media only screen and (min-width: @tabletBreakpoint) { + .ui.scrolling.dropdown .menu, + .ui.dropdown .scrolling.menu { + max-height: @scrollingTabletMaxMenuHeight; + } + } + @media only screen and (min-width: @computerBreakpoint) { + .ui.scrolling.dropdown .menu, + .ui.dropdown .scrolling.menu { + max-height: @scrollingComputerMaxMenuHeight; + } + } + @media only screen and (min-width: @widescreenMonitorBreakpoint) { + .ui.scrolling.dropdown .menu, + .ui.dropdown .scrolling.menu { + max-height: @scrollingWidescreenMaxMenuHeight; + } + } +} + +/*-------------- + Columnar +---------------*/ +.ui.column.dropdown > .menu { + flex-wrap:wrap; +} +.ui.dropdown[class*="two column"] > .menu > .item { + width: 50%; +} +.ui.dropdown[class*="three column"] > .menu > .item { + width: 33%; +} +.ui.dropdown[class*="four column"] > .menu > .item { + width: 25%; +} +.ui.dropdown[class*="five column"] > .menu > .item { + width: 20%; +} + +& when (@variationDropdownSimple) { + /*-------------- + Simple + ---------------*/ + + /* Displays without javascript */ + + .ui.simple.dropdown .menu:before, + .ui.simple.dropdown .menu:after { + display: none; + } + .ui.simple.dropdown .menu { + position: absolute; + /* IE hack to make dropdown icons appear inline */ + display: -ms-inline-flexbox !important; + display: block; + overflow: hidden; + top: -9999px; + opacity: 0; + width: 0; + height: 0; + transition: @simpleTransition; + margin-top: 0 !important; + } + + .ui.simple.active.dropdown, + .ui.simple.dropdown:hover { + border-bottom-left-radius: 0 !important; + border-bottom-right-radius: 0 !important; + } + + .ui.simple.active.dropdown > .menu, + .ui.simple.dropdown:hover > .menu { + overflow: visible; + width: auto; + height: auto; + top: 100%; + opacity: 1; + } + .ui.simple.dropdown > .menu > .item:active > .menu, + .ui.simple.dropdown .menu .item:hover > .menu { + overflow: visible; + width: auto; + height: auto; + top: 0 !important; + left: 100%; + opacity: 1; + } + .ui.simple.dropdown > .menu > .item:active > .left.menu, + .ui.simple.dropdown .menu .item:hover > .left.menu, + .right.menu .ui.simple.dropdown > .menu > .item:active > .menu:not(.right), + .right.menu .ui.simple.dropdown > .menu .item:hover > .menu:not(.right) { + left: auto; + right: 100%; + } + & when (@variationDropdownDisabled) { + .ui.simple.disabled.dropdown:hover .menu { + display: none; + height: 0; + width: 0; + overflow: hidden; + } + } + + /* Visible */ + .ui.simple.visible.dropdown > .menu { + display: block; + } + & when (@variationDropdownScrolling) { + /* Scrolling */ + .ui.simple.scrolling.active.dropdown > .menu, + .ui.simple.scrolling.dropdown:hover > .menu { + overflow-x: hidden; + overflow-y: auto; + } + } +} + +& when (@variationDropdownFluid) { + /*-------------- + Fluid + ---------------*/ + + .ui.fluid.dropdown { + display: block; + width: 100% !important; + min-width: 0; + } + .ui.fluid.dropdown > .dropdown.icon { + float: right; + } +} + +& when (@variationDropdownFloating) { + /*-------------- + Floating + ---------------*/ + + .ui.floating.dropdown .menu { + left: 0; + right: auto; + box-shadow: @floatingMenuBoxShadow !important; + border-radius: @floatingMenuBorderRadius !important; + } + .ui.floating.dropdown > .menu { + border-radius: @floatingMenuBorderRadius !important; + } + .ui:not(.upward).floating.dropdown > .menu { + margin-top: @floatingMenuDistance; + } + .ui.upward.floating.dropdown > .menu { + margin-bottom: @floatingMenuDistance; + } +} + +& when (@variationDropdownPointing) { + /*-------------- + Pointing + ---------------*/ + + .ui.pointing.dropdown > .menu { + top: 100%; + margin-top: @pointingMenuDistance; + border-radius: @pointingMenuBorderRadius; + } + + .ui.pointing.dropdown > .menu:not(.hidden):after { + display: block; + position: absolute; + pointer-events: none; + content: ''; + visibility: visible; + transform: rotate(45deg); + + width: @pointingArrowSize; + height: @pointingArrowSize; + box-shadow: @pointingArrowBoxShadow; + background: @pointingArrowBackground; + z-index: @pointingArrowZIndex; + } + + .ui.pointing.dropdown > .menu:not(.hidden):after { + top: @pointingArrowOffset; + left: 50%; + margin: 0 0 0 @pointingArrowOffset; + } + + /* Top Left Pointing */ + .ui.top.left.pointing.dropdown > .menu { + top: 100%; + bottom: auto; + left: 0; + right: auto; + margin: @pointingArrowDistanceFromEdge 0 0; + } + .ui.top.left.pointing.dropdown > .menu { + top: 100%; + bottom: auto; + left: 0; + right: auto; + margin: @pointingArrowDistanceFromEdge 0 0; + } + .ui.top.left.pointing.dropdown > .menu:after { + top: @pointingArrowOffset; + left: @pointingArrowDistanceFromEdge; + right: auto; + margin: 0; + transform: rotate(45deg); + } + /* Top Right Pointing */ + .ui.top.right.pointing.dropdown > .menu { + top: 100%; + bottom: auto; + right: 0; + left: auto; + margin: @pointingArrowDistanceFromEdge 0 0; + } + .ui.top.pointing.dropdown > .left.menu:after, + .ui.top.right.pointing.dropdown > .menu:after { + top: @pointingArrowOffset; + left: auto !important; + right: @pointingArrowDistanceFromEdge !important; + margin: 0; + transform: rotate(45deg); + } + + /* Left Pointing */ + .ui.left.pointing.dropdown > .menu { + top: 0; + left: 100%; + right: auto; + margin: 0 0 0 @pointingArrowDistanceFromEdge; + } + .ui.left.pointing.dropdown > .menu:after { + top: 1em; + left: @pointingArrowOffset; + margin: 0 0 0 0; + transform: rotate(-45deg); + } + .ui.left:not(.top):not(.bottom).pointing.dropdown > .left.menu { + left: auto !important; + right: 100% !important; + margin: 0 @pointingArrowDistanceFromEdge 0 0; + } + .ui.left:not(.top):not(.bottom).pointing.dropdown > .left.menu:after { + top: 1em; + left: auto; + right: @pointingArrowOffset; + margin: 0 0 0 0; + transform: rotate(135deg); + } + + + /* Right Pointing */ + .ui.right.pointing.dropdown > .menu { + top: 0; + left: auto; + right: 100%; + margin: 0 @pointingArrowDistanceFromEdge 0 0; + } + .ui.right.pointing.dropdown > .menu:after { + top: 1em; + left: auto; + right: @pointingArrowOffset; + margin: 0 0 0 0; + transform: rotate(135deg); + } + + /* Bottom Pointing */ + .ui.bottom.pointing.dropdown > .menu { + top: auto; + bottom: 100%; + left: 0; + right: auto; + margin: 0 0 @pointingArrowDistanceFromEdge ; + } + .ui.bottom.pointing.dropdown > .menu:after { + top: auto; + bottom: @pointingArrowOffset; + right: auto; + margin: 0; + transform: rotate(-135deg); + } + /* Reverse Sub-Menu Direction */ + .ui.bottom.pointing.dropdown > .menu .menu { + top: auto !important; + bottom: 0 !important; + } + + /* Bottom Left */ + .ui.bottom.left.pointing.dropdown > .menu { + left: 0; + right: auto; + } + .ui.bottom.left.pointing.dropdown > .menu:after { + left: @pointingArrowDistanceFromEdge; + right: auto; + } + + /* Bottom Right */ + .ui.bottom.right.pointing.dropdown > .menu { + right: 0; + left: auto; + } + .ui.bottom.right.pointing.dropdown > .menu:after { + left: auto; + right: @pointingArrowDistanceFromEdge; + } + + /* Upward pointing */ + .ui.pointing.upward.dropdown .menu, + .ui.top.pointing.upward.dropdown .menu { + top: auto !important; + bottom: 100% !important; + margin: 0 0 @pointingMenuDistance; + border-radius: @pointingUpwardMenuBorderRadius; + } + .ui.pointing.upward.dropdown .menu:after, + .ui.top.pointing.upward.dropdown .menu:after { + top: 100% !important; + bottom: auto !important; + box-shadow: @pointingUpwardArrowBoxShadow; + margin: @pointingArrowOffset 0 0; + } + + /* Right Pointing Upward */ + .ui.right.pointing.upward.dropdown:not(.top):not(.bottom) .menu { + top: auto !important; + bottom: 0 !important; + margin: 0 @pointingArrowDistanceFromEdge 0 0; + } + .ui.right.pointing.upward.dropdown:not(.top):not(.bottom) .menu:after { + top: auto !important; + bottom: 0 !important; + margin: 0 0 @pointingArrowDistanceFromEdge 0; + box-shadow: @pointingArrowBoxShadow; + } + + + /* Left Pointing Upward */ + .ui.left.pointing.upward.dropdown:not(.top):not(.bottom) .menu { + top: auto !important; + bottom: 0 !important; + margin: 0 0 0 @pointingArrowDistanceFromEdge; + } + .ui.left.pointing.upward.dropdown:not(.top):not(.bottom) .menu:after { + top: auto !important; + bottom: 0 !important; + margin: 0 0 @pointingArrowDistanceFromEdge 0; + box-shadow: @pointingArrowBoxShadow; + } +} + +/*-------------------- + Sizes +---------------------*/ + +.ui.dropdown, +.ui.dropdown .menu > .item { + font-size: @medium; +} +& when not (@variationDropdownSizes = false) { + each(@variationDropdownSizes, { + @s: @@value; + .ui.@{value}.dropdown, + .ui.@{value}.dropdown .menu > .item { + font-size: @s; + } + }) +} + +& when (@variationDropdownInverted) { + /*-------------- + Inverted + ---------------*/ + + /* General rules and basic dropdowns */ + .ui.inverted.dropdown .menu { + background: @invertedMenuBackground; + box-shadow: @invertedMenuBoxShadow; + border: @invertedMenuBorder; + } + + .ui.inverted.dropdown .menu > .item { + color: @invertedMenuColor; + } + + .ui.inverted.dropdown .menu .active.item { + background: @invertedActiveItemBackground; + color: @invertedActiveItemColor; + box-shadow: @invertedActiveItemBoxShadow; + } + + .ui.inverted.dropdown .menu > .item:hover { + background: @invertedHoveredItemBackground; + color: @invertedHoveredItemColor; + } + + .ui.inverted.dropdown.selected, + .ui.inverted.dropdown .menu .selected.item { + background: @invertedSelectedBackground; + color: @invertedSelectedColor; + } + + .ui.inverted.dropdown .menu > .header { + color: @invertedMenuHeaderColor; + } + + .ui.inverted.dropdown > .text > .description, + .ui.inverted.dropdown .menu > .item > .description { + color: @invertedItemDescriptionColor; + } + + .ui.inverted.dropdown .menu > .divider { + border-top: @invertedMenuDividerBorder; + } + + .ui.inverted.dropdown .scrolling.menu { + border: none; + border-top: @invertedMenuBorder; + } + + & when (@variationDropdownSelection) { + /* Selection */ + .ui.inverted.selection.dropdown { + border: @invertedSelectionBorder; + background: @invertedSelectionBackground; + color: @invertedSelectionTextColor; + } + + .ui.inverted.selection.dropdown:hover { + border-color: @invertedSelectionHoverBorderColor; + box-shadow: @invertedSelectionHoverBoxShadow; + } + + .ui.inverted.selection.dropdown input { + color: @invertedSelectionInputTextColor; + } + + .ui.inverted.selection.visible.dropdown > .text:not(.default) { + color: @invertedSelectionVisibleTextColor; + } + + .ui.inverted.selection.active.dropdown .menu, + .ui.inverted.selection.active.dropdown:hover { + border-color: @invertedSelectionVisibleBorderColor; + } + + .ui.inverted.selection.dropdown .menu > .item { + border-top: @invertedSelectionItemDivider; + } + } + + .ui.inverted.dropdown:not(.button) > .default.text, + .ui.inverted.default.dropdown:not(.button) > .text { + color: @invertedDefaultTextColor; + } + .ui.inverted.dropdown:not(.button) > input:focus ~ .default.text, + .ui.inverted.default.dropdown:not(.button) > input:focus ~ .text { + color: @invertedDefaultTextFocusColor; + } + + .ui.inverted.active.search.dropdown input.search:focus + .text i.icon, + .ui.inverted.active.search.dropdown input.search:focus + .text .flag { + opacity: @invertedSelectionTextUnderlayIconOpacity; + } + .ui.inverted.active.search.dropdown input.search:focus + .text { + color: @invertedSelectionTextUnderlayColor !important; + } + + .ui.inverted.dropdown .menu > .message:not(.ui) { + color: @invertedMessageColor; + } + + /* Fixing the border */ + .ui.inverted.dropdown .menu > .item:first-child { + border-top-width: 0; + } + + & when (@variationDropdownMultiple) { + /* Labels */ + .ui.inverted.multiple.dropdown > .label { + background-color: @invertedLabelBackgroundColor; + background-image: @invertedLabelBackgroundImage; + color: @invertedLabelColor; + box-shadow: @invertedLabelBoxShadow; + } + + .ui.inverted.multiple.dropdown > .label:hover { + background-color: @invertedLabelHoverBackgroundColor; + border-color: @invertedLabelHoverBackgroundColor; + + background-image: @invertedLabelHoverBackgroundImage; + color: @invertedLabelHoverTextColor; + } + + .ui.inverted.multiple.dropdown > .label > .close.icon, + .ui.inverted.multiple.dropdown > .label > .delete.icon { + opacity: @invertedLabelIconOpacity; + } + + .ui.inverted.multiple.dropdown > .label > .close.icon:hover, + .ui.inverted.multiple.dropdown > .label > .delete.icon:hover { + opacity: @invertedLabelIconHoverOpacity; + } + } + + /* Selection for form elements */ + .ui.inverted.dropdown textarea::-webkit-selection, + .ui.inverted.dropdown input::-webkit-selection { + background-color: @invertedInputHighlightBackground; + color: @invertedInputHighlightColor; + } + .ui.inverted.dropdown textarea::-moz-selection, + .ui.inverted.dropdown input::-moz-selection { + background-color: @invertedInputHighlightBackground; + color: @invertedInputHighlightColor; + } + .ui.inverted.dropdown textarea::selection, + .ui.inverted.dropdown input::selection { + background-color: @invertedInputHighlightBackground; + color: @invertedInputHighlightColor; + } + + /* Scrollbars */ + .ui.inverted.dropdown .menu::-webkit-scrollbar-track { + background: @trackInvertedBackground; + } + .ui.inverted.dropdown .menu::-webkit-scrollbar-thumb { + background: @thumbInvertedBackground; + } + .ui.inverted.dropdown .menu::-webkit-scrollbar-thumb:window-inactive { + background: @thumbInvertedInactiveBackground; + } + .ui.inverted.dropdown .menu::-webkit-scrollbar-thumb:hover { + background: @thumbInvertedHoverBackground; + } + & when (@variationDropdownPointing) { + .ui.inverted.pointing.dropdown > .menu:after { + background: @invertedPointingArrowBackground; + box-shadow: @invertedPointingArrowBoxShadow; + } + } +} + +.loadUIOverrides(); diff --git a/semantic/src/definitions/modules/embed.js b/semantic/src/definitions/modules/embed.js new file mode 100644 index 0000000..06fed09 --- /dev/null +++ b/semantic/src/definitions/modules/embed.js @@ -0,0 +1,709 @@ +/*! + * # Fomantic-UI - Embed + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +"use strict"; + +$.isFunction = $.isFunction || function(obj) { + return typeof obj === "function" && typeof obj.nodeType !== "number"; +}; + +window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.fn.embed = 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), + + returnedValue + ; + + $allModules + .each(function() { + var + settings = ( $.isPlainObject(parameters) ) + ? $.extend(true, {}, $.fn.embed.settings, parameters) + : $.extend({}, $.fn.embed.settings), + + selector = settings.selector, + className = settings.className, + sources = settings.sources, + error = settings.error, + metadata = settings.metadata, + namespace = settings.namespace, + templates = settings.templates, + + eventNamespace = '.' + namespace, + moduleNamespace = 'module-' + namespace, + + $module = $(this), + $placeholder = $module.find(selector.placeholder), + $icon = $module.find(selector.icon), + $embed = $module.find(selector.embed), + + element = this, + instance = $module.data(moduleNamespace), + module + ; + + module = { + + initialize: function() { + module.debug('Initializing embed'); + module.determine.autoplay(); + module.create(); + module.bind.events(); + module.instantiate(); + }, + + instantiate: function() { + module.verbose('Storing instance of module', module); + instance = module; + $module + .data(moduleNamespace, module) + ; + }, + + destroy: function() { + module.verbose('Destroying previous instance of embed'); + module.reset(); + $module + .removeData(moduleNamespace) + .off(eventNamespace) + ; + }, + + refresh: function() { + module.verbose('Refreshing selector cache'); + $placeholder = $module.find(selector.placeholder); + $icon = $module.find(selector.icon); + $embed = $module.find(selector.embed); + }, + + bind: { + events: function() { + if( module.has.placeholder() ) { + module.debug('Adding placeholder events'); + $module + .on('click' + eventNamespace, selector.placeholder, module.createAndShow) + .on('click' + eventNamespace, selector.icon, module.createAndShow) + ; + } + } + }, + + create: function() { + var + placeholder = module.get.placeholder() + ; + if(placeholder) { + module.createPlaceholder(); + } + else { + module.createAndShow(); + } + }, + + createPlaceholder: function(placeholder) { + var + icon = module.get.icon(), + url = module.get.url(), + embed = module.generate.embed(url) + ; + placeholder = placeholder || module.get.placeholder(); + $module.html( templates.placeholder(placeholder, icon) ); + module.debug('Creating placeholder for embed', placeholder, icon); + }, + + createEmbed: function(url) { + module.refresh(); + url = url || module.get.url(); + $embed = $('<div/>') + .addClass(className.embed) + .html( module.generate.embed(url) ) + .appendTo($module) + ; + settings.onCreate.call(element, url); + module.debug('Creating embed object', $embed); + }, + + changeEmbed: function(url) { + $embed + .html( module.generate.embed(url) ) + ; + }, + + createAndShow: function() { + module.createEmbed(); + module.show(); + }, + + // sets new embed + change: function(source, id, url) { + module.debug('Changing video to ', source, id, url); + $module + .data(metadata.source, source) + .data(metadata.id, id) + ; + if(url) { + $module.data(metadata.url, url); + } + else { + $module.removeData(metadata.url); + } + if(module.has.embed()) { + module.changeEmbed(); + } + else { + module.create(); + } + }, + + // clears embed + reset: function() { + module.debug('Clearing embed and showing placeholder'); + module.remove.data(); + module.remove.active(); + module.remove.embed(); + module.showPlaceholder(); + settings.onReset.call(element); + }, + + // shows current embed + show: function() { + module.debug('Showing embed'); + module.set.active(); + settings.onDisplay.call(element); + }, + + hide: function() { + module.debug('Hiding embed'); + module.showPlaceholder(); + }, + + showPlaceholder: function() { + module.debug('Showing placeholder image'); + module.remove.active(); + settings.onPlaceholderDisplay.call(element); + }, + + get: { + id: function() { + return settings.id || $module.data(metadata.id); + }, + placeholder: function() { + return settings.placeholder || $module.data(metadata.placeholder); + }, + icon: function() { + return (settings.icon) + ? settings.icon + : ($module.data(metadata.icon) !== undefined) + ? $module.data(metadata.icon) + : module.determine.icon() + ; + }, + source: function(url) { + return (settings.source) + ? settings.source + : ($module.data(metadata.source) !== undefined) + ? $module.data(metadata.source) + : module.determine.source() + ; + }, + type: function() { + var source = module.get.source(); + return (sources[source] !== undefined) + ? sources[source].type + : false + ; + }, + url: function() { + return (settings.url) + ? settings.url + : ($module.data(metadata.url) !== undefined) + ? $module.data(metadata.url) + : module.determine.url() + ; + } + }, + + determine: { + autoplay: function() { + if(module.should.autoplay()) { + settings.autoplay = true; + } + }, + source: function(url) { + var + matchedSource = false + ; + url = url || module.get.url(); + if(url) { + $.each(sources, function(name, source) { + if(url.search(source.domain) !== -1) { + matchedSource = name; + return false; + } + }); + } + return matchedSource; + }, + icon: function() { + var + source = module.get.source() + ; + return (sources[source] !== undefined) + ? sources[source].icon + : false + ; + }, + url: function() { + var + id = settings.id || $module.data(metadata.id), + source = settings.source || $module.data(metadata.source), + url + ; + url = (sources[source] !== undefined) + ? sources[source].url.replace('{id}', id) + : false + ; + if(url) { + $module.data(metadata.url, url); + } + return url; + } + }, + + + set: { + active: function() { + $module.addClass(className.active); + } + }, + + remove: { + data: function() { + $module + .removeData(metadata.id) + .removeData(metadata.icon) + .removeData(metadata.placeholder) + .removeData(metadata.source) + .removeData(metadata.url) + ; + }, + active: function() { + $module.removeClass(className.active); + }, + embed: function() { + $embed.empty(); + } + }, + + encode: { + parameters: function(parameters) { + var + urlString = [], + index + ; + for (index in parameters) { + urlString.push( encodeURIComponent(index) + '=' + encodeURIComponent( parameters[index] ) ); + } + return urlString.join('&'); + } + }, + + generate: { + embed: function(url) { + module.debug('Generating embed html'); + var + source = module.get.source(), + html, + parameters + ; + url = module.get.url(url); + if(url) { + parameters = module.generate.parameters(source); + html = templates.iframe(url, parameters); + } + else { + module.error(error.noURL, $module); + } + return html; + }, + parameters: function(source, extraParameters) { + var + parameters = (sources[source] && sources[source].parameters !== undefined) + ? sources[source].parameters(settings) + : {} + ; + extraParameters = extraParameters || settings.parameters; + if(extraParameters) { + parameters = $.extend({}, parameters, extraParameters); + } + parameters = settings.onEmbed(parameters); + return module.encode.parameters(parameters); + } + }, + + has: { + embed: function() { + return ($embed.length > 0); + }, + placeholder: function() { + return settings.placeholder || $module.data(metadata.placeholder); + } + }, + + should: { + autoplay: function() { + return (settings.autoplay === 'auto') + ? (settings.placeholder || $module.data(metadata.placeholder) !== undefined) + : settings.autoplay + ; + } + }, + + is: { + video: function() { + return module.get.type() == 'video'; + } + }, + + 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($allModules.length > 1) { + title += ' ' + '(' + $allModules.length + ')'; + } + 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(Array.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.embed.settings = { + + name : 'Embed', + namespace : 'embed', + + silent : false, + debug : false, + verbose : false, + performance : true, + + icon : false, + source : false, + url : false, + id : false, + + // standard video settings + autoplay : 'auto', + color : '#444444', + hd : true, + brandedUI : false, + + // additional parameters to include with the embed + parameters: false, + + onDisplay : function() {}, + onPlaceholderDisplay : function() {}, + onReset : function() {}, + onCreate : function(url) {}, + onEmbed : function(parameters) { + return parameters; + }, + + metadata : { + id : 'id', + icon : 'icon', + placeholder : 'placeholder', + source : 'source', + url : 'url' + }, + + error : { + noURL : 'No URL specified', + method : 'The method you called is not defined' + }, + + className : { + active : 'active', + embed : 'embed' + }, + + selector : { + embed : '.embed', + placeholder : '.placeholder', + icon : '.icon' + }, + + sources: { + youtube: { + name : 'youtube', + type : 'video', + icon : 'video play', + domain : 'youtube.com', + url : '//www.youtube.com/embed/{id}', + parameters: function(settings) { + return { + autohide : !settings.brandedUI, + autoplay : settings.autoplay, + color : settings.color || undefined, + hq : settings.hd, + jsapi : settings.api, + modestbranding : !settings.brandedUI + }; + } + }, + vimeo: { + name : 'vimeo', + type : 'video', + icon : 'video play', + domain : 'vimeo.com', + url : '//player.vimeo.com/video/{id}', + parameters: function(settings) { + return { + api : settings.api, + autoplay : settings.autoplay, + byline : settings.brandedUI, + color : settings.color || undefined, + portrait : settings.brandedUI, + title : settings.brandedUI + }; + } + } + }, + + templates: { + iframe : function(url, parameters) { + var src = url; + if (parameters) { + src += '?' + parameters; + } + return '' + + '<iframe src="' + src + '"' + + ' width="100%" height="100%"' + + ' webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>' + ; + }, + placeholder : function(image, icon) { + var + html = '' + ; + if(icon) { + html += '<i class="' + icon + ' icon"></i>'; + } + if(image) { + html += '<img class="placeholder" src="' + image + '">'; + } + return html; + } + }, + + // NOT YET IMPLEMENTED + api : false, + onPause : function() {}, + onPlay : function() {}, + onStop : function() {} + +}; + + + +})( jQuery, window, document ); diff --git a/semantic/src/definitions/modules/embed.less b/semantic/src/definitions/modules/embed.less new file mode 100644 index 0000000..46f13a0 --- /dev/null +++ b/semantic/src/definitions/modules/embed.less @@ -0,0 +1,160 @@ +/*! + * # Fomantic-UI - Video + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + + +/******************************* + Theme +*******************************/ + +@type : 'module'; +@element : 'embed'; + +@import (multiple) '../../theme.config'; + +/******************************* + Types +*******************************/ + +.ui.embed { + position: relative; + max-width: 100%; + height: 0; + overflow: hidden; + background: @background; + padding-bottom: @widescreenRatio; +} + +/*----------------- + Embedded Content +------------------*/ + +.ui.embed iframe, +.ui.embed embed, +.ui.embed object { + position: absolute; + border: none; + width: 100%; + height: 100%; + top: 0; + left: 0; + margin: 0; + padding: 0; + overflow: hidden; +} + +/*----------------- + Embed +------------------*/ + +.ui.embed > .embed { + display: none; +} + +/*-------------- + Placeholder +---------------*/ + +.ui.embed > .placeholder { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + display: block; + width: 100%; + height: 100%; + background-color: @placeholderBackground; +} + +/*-------------- + Icon +---------------*/ + +.ui.embed > i.icon { + cursor: pointer; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 2; +} +.ui.embed > i.icon:after { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 3; + content: ''; + background: @placeholderBackground; + opacity: @placeholderBackgroundOpacity; + transition: @placeholderBackgroundTransition; +} +.ui.embed > i.icon:before { + position: absolute; + top: 50%; + left: 50%; + transform: translateX(-50%) translateY(-50%); + + color: @iconColor; + font-size: @iconSize; + text-shadow: @iconShadow; + transition: @iconTransition; + z-index: @iconZIndex; +} + +/******************************* + States +*******************************/ + +/*-------------- + Hover +---------------*/ + +.ui.embed i.icon:hover:after { + background: @hoverPlaceholderBackground; + opacity: @hoverPlaceholderBackgroundOpacity; +} +.ui.embed i.icon:hover:before { + color: @hoverIconColor; +} + +/*-------------- + Active +---------------*/ + +.ui.active.embed > i.icon, +.ui.active.embed > .placeholder { + display: none; +} +.ui.active.embed > .embed { + display: block; +} + +/******************************* + Variations +*******************************/ + +& when (@variationEmbedRatio) { + .ui.square.embed { + padding-bottom: @squareRatio; + } + .ui[class*="4:3"].embed { + padding-bottom: @standardRatio; + } + .ui[class*="16:9"].embed { + padding-bottom: @widescreenRatio; + } + .ui[class*="21:9"].embed { + padding-bottom: @ultraWidescreenRatio; + } +} + +.loadUIOverrides(); diff --git a/semantic/src/definitions/modules/modal.js b/semantic/src/definitions/modules/modal.js new file mode 100644 index 0000000..420ecc2 --- /dev/null +++ b/semantic/src/definitions/modules/modal.js @@ -0,0 +1,1209 @@ +/*! + * # Fomantic-UI - Modal + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +'use strict'; + +$.isFunction = $.isFunction || function(obj) { + return typeof obj === "function" && typeof obj.nodeType !== "number"; +}; + +window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.fn.modal = function(parameters) { + var + $allModules = $(this), + $window = $(window), + $document = $(document), + $body = $('body'), + + moduleSelector = $allModules.selector || '', + + time = new Date().getTime(), + performance = [], + + query = arguments[0], + methodInvoked = (typeof query == 'string'), + queryArguments = [].slice.call(arguments, 1), + + requestAnimationFrame = window.requestAnimationFrame + || window.mozRequestAnimationFrame + || window.webkitRequestAnimationFrame + || window.msRequestAnimationFrame + || function(callback) { setTimeout(callback, 0); }, + + returnedValue + ; + + $allModules + .each(function() { + var + settings = ( $.isPlainObject(parameters) ) + ? $.extend(true, {}, $.fn.modal.settings, parameters) + : $.extend({}, $.fn.modal.settings), + + selector = settings.selector, + className = settings.className, + namespace = settings.namespace, + error = settings.error, + + eventNamespace = '.' + namespace, + moduleNamespace = 'module-' + namespace, + + $module = $(this), + $context = $(settings.context), + $close = $module.find(selector.close), + + $allModals, + $otherModals, + $focusedElement, + $dimmable, + $dimmer, + + element = this, + instance = $module.data(moduleNamespace), + + ignoreRepeatedEvents = false, + + initialMouseDownInModal, + initialMouseDownInScrollbar, + initialBodyMargin = '', + tempBodyMargin = '', + + elementEventNamespace, + id, + observer, + module + ; + module = { + + initialize: function() { + module.cache = {}; + module.verbose('Initializing dimmer', $context); + + module.create.id(); + module.create.dimmer(); + + if ( settings.allowMultiple ) { + module.create.innerDimmer(); + } + if (!settings.centered){ + $module.addClass('top aligned'); + } + module.refreshModals(); + + module.bind.events(); + if(settings.observeChanges) { + module.observeChanges(); + } + module.instantiate(); + }, + + instantiate: function() { + module.verbose('Storing instance of modal'); + instance = module; + $module + .data(moduleNamespace, instance) + ; + }, + + create: { + dimmer: function() { + var + defaultSettings = { + debug : settings.debug, + dimmerName : 'modals' + }, + dimmerSettings = $.extend(true, defaultSettings, settings.dimmerSettings) + ; + if($.fn.dimmer === undefined) { + module.error(error.dimmer); + return; + } + module.debug('Creating dimmer'); + $dimmable = $context.dimmer(dimmerSettings); + if(settings.detachable) { + module.verbose('Modal is detachable, moving content into dimmer'); + $dimmable.dimmer('add content', $module); + } + else { + module.set.undetached(); + } + $dimmer = $dimmable.dimmer('get dimmer'); + }, + id: function() { + id = (Math.random().toString(16) + '000000000').substr(2, 8); + elementEventNamespace = '.' + id; + module.verbose('Creating unique id for element', id); + }, + innerDimmer: function() { + if ( $module.find(selector.dimmer).length == 0 ) { + $module.prepend('<div class="ui inverted dimmer"></div>'); + } + } + }, + + destroy: function() { + if (observer) { + observer.disconnect(); + } + module.verbose('Destroying previous modal'); + $module + .removeData(moduleNamespace) + .off(eventNamespace) + ; + $window.off(elementEventNamespace); + $dimmer.off(elementEventNamespace); + $close.off(eventNamespace); + $context.dimmer('destroy'); + }, + + observeChanges: function() { + if('MutationObserver' in window) { + observer = new MutationObserver(function(mutations) { + module.debug('DOM tree modified, refreshing'); + module.refresh(); + }); + observer.observe(element, { + childList : true, + subtree : true + }); + module.debug('Setting up mutation observer', observer); + } + }, + + refresh: function() { + module.remove.scrolling(); + module.cacheSizes(); + if(!module.can.useFlex()) { + module.set.modalOffset(); + } + module.set.screenHeight(); + module.set.type(); + }, + + refreshModals: function() { + $otherModals = $module.siblings(selector.modal); + $allModals = $otherModals.add($module); + }, + + attachEvents: function(selector, event) { + var + $toggle = $(selector) + ; + event = $.isFunction(module[event]) + ? module[event] + : module.toggle + ; + if($toggle.length > 0) { + module.debug('Attaching modal events to element', selector, event); + $toggle + .off(eventNamespace) + .on('click' + eventNamespace, event) + ; + } + else { + module.error(error.notFound, selector); + } + }, + + bind: { + events: function() { + module.verbose('Attaching events'); + $module + .on('click' + eventNamespace, selector.close, module.event.close) + .on('click' + eventNamespace, selector.approve, module.event.approve) + .on('click' + eventNamespace, selector.deny, module.event.deny) + ; + $window + .on('resize' + elementEventNamespace, module.event.resize) + ; + }, + scrollLock: function() { + // touch events default to passive, due to changes in chrome to optimize mobile perf + $dimmable.get(0).addEventListener('touchmove', module.event.preventScroll, { passive: false }); + } + }, + + unbind: { + scrollLock: function() { + $dimmable.get(0).removeEventListener('touchmove', module.event.preventScroll, { passive: false }); + } + }, + + get: { + id: function() { + return (Math.random().toString(16) + '000000000').substr(2, 8); + } + }, + + event: { + approve: function() { + if(ignoreRepeatedEvents || settings.onApprove.call(element, $(this)) === false) { + module.verbose('Approve callback returned false cancelling hide'); + return; + } + ignoreRepeatedEvents = true; + module.hide(function() { + ignoreRepeatedEvents = false; + }); + }, + preventScroll: function(event) { + if(event.target.className.indexOf('dimmer') !== -1) { + event.preventDefault(); + } + }, + deny: function() { + if(ignoreRepeatedEvents || settings.onDeny.call(element, $(this)) === false) { + module.verbose('Deny callback returned false cancelling hide'); + return; + } + ignoreRepeatedEvents = true; + module.hide(function() { + ignoreRepeatedEvents = false; + }); + }, + close: function() { + module.hide(); + }, + mousedown: function(event) { + var + $target = $(event.target), + isRtl = module.is.rtl(); + ; + initialMouseDownInModal = ($target.closest(selector.modal).length > 0); + if(initialMouseDownInModal) { + module.verbose('Mouse down event registered inside the modal'); + } + initialMouseDownInScrollbar = module.is.scrolling() && ((!isRtl && $(window).outerWidth() - settings.scrollbarWidth <= event.clientX) || (isRtl && settings.scrollbarWidth >= event.clientX)); + if(initialMouseDownInScrollbar) { + module.verbose('Mouse down event registered inside the scrollbar'); + } + }, + mouseup: function(event) { + if(!settings.closable) { + module.verbose('Dimmer clicked but closable setting is disabled'); + return; + } + if(initialMouseDownInModal) { + module.debug('Dimmer clicked but mouse down was initially registered inside the modal'); + return; + } + if(initialMouseDownInScrollbar){ + module.debug('Dimmer clicked but mouse down was initially registered inside the scrollbar'); + return; + } + var + $target = $(event.target), + isInModal = ($target.closest(selector.modal).length > 0), + isInDOM = $.contains(document.documentElement, event.target) + ; + if(!isInModal && isInDOM && module.is.active() && $module.hasClass(className.front) ) { + module.debug('Dimmer clicked, hiding all modals'); + if(settings.allowMultiple) { + if(!module.hideAll()) { + return; + } + } + else if(!module.hide()){ + return; + } + module.remove.clickaway(); + } + }, + debounce: function(method, delay) { + clearTimeout(module.timer); + module.timer = setTimeout(method, delay); + }, + keyboard: function(event) { + var + keyCode = event.which, + escapeKey = 27 + ; + if(keyCode == escapeKey) { + if(settings.closable) { + module.debug('Escape key pressed hiding modal'); + if ( $module.hasClass(className.front) ) { + module.hide(); + } + } + else { + module.debug('Escape key pressed, but closable is set to false'); + } + event.preventDefault(); + } + }, + resize: function() { + if( $dimmable.dimmer('is active') && ( module.is.animating() || module.is.active() ) ) { + requestAnimationFrame(module.refresh); + } + } + }, + + toggle: function() { + if( module.is.active() || module.is.animating() ) { + module.hide(); + } + else { + module.show(); + } + }, + + show: function(callback) { + callback = $.isFunction(callback) + ? callback + : function(){} + ; + module.refreshModals(); + module.set.dimmerSettings(); + module.set.dimmerStyles(); + + module.showModal(callback); + }, + + hide: function(callback) { + callback = $.isFunction(callback) + ? callback + : function(){} + ; + module.refreshModals(); + return module.hideModal(callback); + }, + + showModal: function(callback) { + callback = $.isFunction(callback) + ? callback + : function(){} + ; + if( module.is.animating() || !module.is.active() ) { + module.showDimmer(); + module.cacheSizes(); + module.set.bodyMargin(); + if(module.can.useFlex()) { + module.remove.legacy(); + } + else { + module.set.legacy(); + module.set.modalOffset(); + module.debug('Using non-flex legacy modal positioning.'); + } + module.set.screenHeight(); + module.set.type(); + module.set.clickaway(); + + if( !settings.allowMultiple && module.others.active() ) { + module.hideOthers(module.showModal); + } + else { + ignoreRepeatedEvents = false; + if( settings.allowMultiple ) { + if ( module.others.active() ) { + $otherModals.filter('.' + className.active).find(selector.dimmer).addClass('active'); + } + + if ( settings.detachable ) { + $module.detach().appendTo($dimmer); + } + } + settings.onShow.call(element); + if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { + module.debug('Showing modal with css animations'); + $module + .transition({ + debug : settings.debug, + animation : settings.transition + ' in', + queue : settings.queue, + duration : settings.duration, + useFailSafe : true, + onComplete : function() { + settings.onVisible.apply(element); + if(settings.keyboardShortcuts) { + module.add.keyboardShortcuts(); + } + module.save.focus(); + module.set.active(); + if(settings.autofocus) { + module.set.autofocus(); + } + callback(); + } + }) + ; + } + else { + module.error(error.noTransition); + } + } + } + else { + module.debug('Modal is already visible'); + } + }, + + hideModal: function(callback, keepDimmed, hideOthersToo) { + var + $previousModal = $otherModals.filter('.' + className.active).last() + ; + callback = $.isFunction(callback) + ? callback + : function(){} + ; + module.debug('Hiding modal'); + if(settings.onHide.call(element, $(this)) === false) { + module.verbose('Hide callback returned false cancelling hide'); + ignoreRepeatedEvents = false; + return false; + } + + if( module.is.animating() || module.is.active() ) { + if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { + module.remove.active(); + $module + .transition({ + debug : settings.debug, + animation : settings.transition + ' out', + queue : settings.queue, + duration : settings.duration, + useFailSafe : true, + onStart : function() { + if(!module.others.active() && !module.others.animating() && !keepDimmed) { + module.hideDimmer(); + } + if( settings.keyboardShortcuts && !module.others.active() ) { + module.remove.keyboardShortcuts(); + } + }, + onComplete : function() { + module.unbind.scrollLock(); + if ( settings.allowMultiple ) { + $previousModal.addClass(className.front); + $module.removeClass(className.front); + + if ( hideOthersToo ) { + $allModals.find(selector.dimmer).removeClass('active'); + } + else { + $previousModal.find(selector.dimmer).removeClass('active'); + } + } + settings.onHidden.call(element); + module.remove.dimmerStyles(); + module.restore.focus(); + callback(); + } + }) + ; + } + else { + module.error(error.noTransition); + } + } + }, + + showDimmer: function() { + if($dimmable.dimmer('is animating') || !$dimmable.dimmer('is active') ) { + module.save.bodyMargin(); + module.debug('Showing dimmer'); + $dimmable.dimmer('show'); + } + else { + module.debug('Dimmer already visible'); + } + }, + + hideDimmer: function() { + if( $dimmable.dimmer('is animating') || ($dimmable.dimmer('is active')) ) { + module.unbind.scrollLock(); + $dimmable.dimmer('hide', function() { + module.restore.bodyMargin(); + module.remove.clickaway(); + module.remove.screenHeight(); + }); + } + else { + module.debug('Dimmer is not visible cannot hide'); + return; + } + }, + + hideAll: function(callback) { + var + $visibleModals = $allModals.filter('.' + className.active + ', .' + className.animating) + ; + callback = $.isFunction(callback) + ? callback + : function(){} + ; + if( $visibleModals.length > 0 ) { + module.debug('Hiding all visible modals'); + var hideOk = true; +//check in reverse order trying to hide most top displayed modal first + $($visibleModals.get().reverse()).each(function(index,element){ + if(hideOk){ + hideOk = $(element).modal('hide modal', callback, false, true); + } + }); + if(hideOk) { + module.hideDimmer(); + } + return hideOk; + } + }, + + hideOthers: function(callback) { + var + $visibleModals = $otherModals.filter('.' + className.active + ', .' + className.animating) + ; + callback = $.isFunction(callback) + ? callback + : function(){} + ; + if( $visibleModals.length > 0 ) { + module.debug('Hiding other modals', $otherModals); + $visibleModals + .modal('hide modal', callback, true) + ; + } + }, + + others: { + active: function() { + return ($otherModals.filter('.' + className.active).length > 0); + }, + animating: function() { + return ($otherModals.filter('.' + className.animating).length > 0); + } + }, + + + add: { + keyboardShortcuts: function() { + module.verbose('Adding keyboard shortcuts'); + $document + .on('keyup' + eventNamespace, module.event.keyboard) + ; + } + }, + + save: { + focus: function() { + var + $activeElement = $(document.activeElement), + inCurrentModal = $activeElement.closest($module).length > 0 + ; + if(!inCurrentModal) { + $focusedElement = $(document.activeElement).blur(); + } + }, + bodyMargin: function() { + initialBodyMargin = $body.css('margin-'+(module.can.leftBodyScrollbar() ? 'left':'right')); + var bodyMarginRightPixel = parseInt(initialBodyMargin.replace(/[^\d.]/g, '')), + bodyScrollbarWidth = window.innerWidth - document.documentElement.clientWidth; + tempBodyMargin = bodyMarginRightPixel + bodyScrollbarWidth; + } + }, + + restore: { + focus: function() { + if($focusedElement && $focusedElement.length > 0 && settings.restoreFocus) { + $focusedElement.focus(); + } + }, + bodyMargin: function() { + var position = module.can.leftBodyScrollbar() ? 'left':'right'; + $body.css('margin-'+position, initialBodyMargin); + $body.find(selector.bodyFixed.replace('right',position)).css('padding-'+position, initialBodyMargin); + } + }, + + remove: { + active: function() { + $module.removeClass(className.active); + }, + legacy: function() { + $module.removeClass(className.legacy); + }, + clickaway: function() { + if (!settings.detachable) { + $module + .off('mousedown' + elementEventNamespace) + ; + } + $dimmer + .off('mousedown' + elementEventNamespace) + ; + $dimmer + .off('mouseup' + elementEventNamespace) + ; + }, + dimmerStyles: function() { + $dimmer.removeClass(className.inverted); + $dimmable.removeClass(className.blurring); + }, + bodyStyle: function() { + if($body.attr('style') === '') { + module.verbose('Removing style attribute'); + $body.removeAttr('style'); + } + }, + screenHeight: function() { + module.debug('Removing page height'); + $body + .css('height', '') + ; + }, + keyboardShortcuts: function() { + module.verbose('Removing keyboard shortcuts'); + $document + .off('keyup' + eventNamespace) + ; + }, + scrolling: function() { + $dimmable.removeClass(className.scrolling); + $module.removeClass(className.scrolling); + } + }, + + cacheSizes: function() { + $module.addClass(className.loading); + var + scrollHeight = $module.prop('scrollHeight'), + modalWidth = $module.outerWidth(), + modalHeight = $module.outerHeight() + ; + if(module.cache.pageHeight === undefined || modalHeight !== 0) { + $.extend(module.cache, { + pageHeight : $(document).outerHeight(), + width : modalWidth, + height : modalHeight + settings.offset, + scrollHeight : scrollHeight + settings.offset, + contextHeight : (settings.context == 'body') + ? $(window).height() + : $dimmable.height(), + }); + module.cache.topOffset = -(module.cache.height / 2); + } + $module.removeClass(className.loading); + module.debug('Caching modal and container sizes', module.cache); + }, + + can: { + leftBodyScrollbar: function(){ + if(module.cache.leftBodyScrollbar === undefined) { + module.cache.leftBodyScrollbar = module.is.rtl() && ((module.is.iframe && !module.is.firefox()) || module.is.safari() || module.is.edge() || module.is.ie()); + } + return module.cache.leftBodyScrollbar; + }, + useFlex: function() { + if (settings.useFlex === 'auto') { + return settings.detachable && !module.is.ie(); + } + if(settings.useFlex && module.is.ie()) { + module.debug('useFlex true is not supported in IE'); + } else if(settings.useFlex && !settings.detachable) { + module.debug('useFlex true in combination with detachable false is not supported'); + } + return settings.useFlex; + }, + fit: function() { + var + contextHeight = module.cache.contextHeight, + verticalCenter = module.cache.contextHeight / 2, + topOffset = module.cache.topOffset, + scrollHeight = module.cache.scrollHeight, + height = module.cache.height, + paddingHeight = settings.padding, + startPosition = (verticalCenter + topOffset) + ; + return (scrollHeight > height) + ? (startPosition + scrollHeight + paddingHeight < contextHeight) + : (height + (paddingHeight * 2) < contextHeight) + ; + } + }, + + is: { + active: function() { + return $module.hasClass(className.active); + }, + ie: function() { + if(module.cache.isIE === undefined) { + var + isIE11 = (!(window.ActiveXObject) && 'ActiveXObject' in window), + isIE = ('ActiveXObject' in window) + ; + module.cache.isIE = (isIE11 || isIE); + } + return module.cache.isIE; + }, + animating: function() { + return $module.transition('is supported') + ? $module.transition('is animating') + : $module.is(':visible') + ; + }, + scrolling: function() { + return $dimmable.hasClass(className.scrolling); + }, + modernBrowser: function() { + // appName for IE11 reports 'Netscape' can no longer use + return !(window.ActiveXObject || 'ActiveXObject' in window); + }, + rtl: function() { + if(module.cache.isRTL === undefined) { + module.cache.isRTL = $body.attr('dir') === 'rtl' || $body.css('direction') === 'rtl'; + } + return module.cache.isRTL; + }, + safari: function() { + if(module.cache.isSafari === undefined) { + module.cache.isSafari = /constructor/i.test(window.HTMLElement) || !!window.ApplePaySession; + } + return module.cache.isSafari; + }, + edge: function(){ + if(module.cache.isEdge === undefined) { + module.cache.isEdge = !!window.setImmediate && !module.is.ie(); + } + return module.cache.isEdge; + }, + firefox: function(){ + if(module.cache.isFirefox === undefined) { + module.cache.isFirefox = !!window.InstallTrigger; + } + return module.cache.isFirefox; + }, + iframe: function() { + return !(self === top); + } + }, + + set: { + autofocus: function() { + var + $inputs = $module.find('[tabindex], :input').filter(':visible').filter(function() { + return $(this).closest('.disabled').length === 0; + }), + $autofocus = $inputs.filter('[autofocus]'), + $input = ($autofocus.length > 0) + ? $autofocus.first() + : $inputs.first() + ; + if($input.length > 0) { + $input.focus(); + } + }, + bodyMargin: function() { + var position = module.can.leftBodyScrollbar() ? 'left':'right'; + if(settings.detachable || module.can.fit()) { + $body.css('margin-'+position, tempBodyMargin + 'px'); + } + $body.find(selector.bodyFixed.replace('right',position)).css('padding-'+position, tempBodyMargin + 'px'); + }, + clickaway: function() { + if (!settings.detachable) { + $module + .on('mousedown' + elementEventNamespace, module.event.mousedown) + ; + } + $dimmer + .on('mousedown' + elementEventNamespace, module.event.mousedown) + ; + $dimmer + .on('mouseup' + elementEventNamespace, module.event.mouseup) + ; + }, + dimmerSettings: function() { + if($.fn.dimmer === undefined) { + module.error(error.dimmer); + return; + } + var + defaultSettings = { + debug : settings.debug, + dimmerName : 'modals', + closable : 'auto', + useFlex : module.can.useFlex(), + duration : { + show : settings.duration, + hide : settings.duration + } + }, + dimmerSettings = $.extend(true, defaultSettings, settings.dimmerSettings) + ; + if(settings.inverted) { + dimmerSettings.variation = (dimmerSettings.variation !== undefined) + ? dimmerSettings.variation + ' inverted' + : 'inverted' + ; + } + $context.dimmer('setting', dimmerSettings); + }, + dimmerStyles: function() { + if(settings.inverted) { + $dimmer.addClass(className.inverted); + } + else { + $dimmer.removeClass(className.inverted); + } + if(settings.blurring) { + $dimmable.addClass(className.blurring); + } + else { + $dimmable.removeClass(className.blurring); + } + }, + modalOffset: function() { + if (!settings.detachable) { + var canFit = module.can.fit(); + $module + .css({ + top: (!$module.hasClass('aligned') && canFit) + ? $(document).scrollTop() + (module.cache.contextHeight - module.cache.height) / 2 + : !canFit || $module.hasClass('top') + ? $(document).scrollTop() + settings.padding + : $(document).scrollTop() + (module.cache.contextHeight - module.cache.height - settings.padding), + marginLeft: -(module.cache.width / 2) + }) + ; + } else { + $module + .css({ + marginTop: (!$module.hasClass('aligned') && module.can.fit()) + ? -(module.cache.height / 2) + : settings.padding / 2, + marginLeft: -(module.cache.width / 2) + }) + ; + } + module.verbose('Setting modal offset for legacy mode'); + }, + screenHeight: function() { + if( module.can.fit() ) { + $body.css('height', ''); + } + else if(!$module.hasClass('bottom')) { + module.debug('Modal is taller than page content, resizing page height'); + $body + .css('height', module.cache.height + (settings.padding * 2) ) + ; + } + }, + active: function() { + $module.addClass(className.active + ' ' + className.front); + $otherModals.filter('.' + className.active).removeClass(className.front); + }, + scrolling: function() { + $dimmable.addClass(className.scrolling); + $module.addClass(className.scrolling); + module.unbind.scrollLock(); + }, + legacy: function() { + $module.addClass(className.legacy); + }, + type: function() { + if(module.can.fit()) { + module.verbose('Modal fits on screen'); + if(!module.others.active() && !module.others.animating()) { + module.remove.scrolling(); + module.bind.scrollLock(); + } + } + else if (!$module.hasClass('bottom')){ + module.verbose('Modal cannot fit on screen setting to scrolling'); + module.set.scrolling(); + } else { + module.verbose('Bottom aligned modal not fitting on screen is unsupported for scrolling'); + } + }, + undetached: function() { + $dimmable.addClass(className.undetached); + } + }, + + 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 { + return false; + } + }); + } + if ( $.isFunction( found ) ) { + response = found.apply(context, passedArguments); + } + else if(found !== undefined) { + response = found; + } + if(Array.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.modal.settings = { + + name : 'Modal', + namespace : 'modal', + + useFlex : 'auto', + offset : 0, + + silent : false, + debug : false, + verbose : false, + performance : true, + + observeChanges : false, + + allowMultiple : false, + detachable : true, + closable : true, + autofocus : true, + restoreFocus : true, + + inverted : false, + blurring : false, + + centered : true, + + dimmerSettings : { + closable : false, + useCSS : true + }, + + // whether to use keyboard shortcuts + keyboardShortcuts: true, + + context : 'body', + + queue : false, + duration : 500, + transition : 'scale', + + // padding with edge of page + padding : 50, + scrollbarWidth: 10, + + // called before show animation + onShow : function(){}, + + // called after show animation + onVisible : function(){}, + + // called before hide animation + onHide : function(){ return true; }, + + // called after hide animation + onHidden : function(){}, + + // called after approve selector match + onApprove : function(){ return true; }, + + // called after deny selector match + onDeny : function(){ return true; }, + + selector : { + close : '> .close', + approve : '.actions .positive, .actions .approve, .actions .ok', + deny : '.actions .negative, .actions .deny, .actions .cancel', + modal : '.ui.modal', + dimmer : '> .ui.dimmer', + bodyFixed: '> .ui.fixed.menu, > .ui.right.toast-container, > .ui.right.sidebar' + }, + error : { + dimmer : 'UI Dimmer, a required component is not included in this page', + method : 'The method you called is not defined.', + notFound : 'The element you specified could not be found' + }, + className : { + active : 'active', + animating : 'animating', + blurring : 'blurring', + inverted : 'inverted', + legacy : 'legacy', + loading : 'loading', + scrolling : 'scrolling', + undetached : 'undetached', + front : 'front' + } +}; + + +})( jQuery, window, document ); diff --git a/semantic/src/definitions/modules/modal.less b/semantic/src/definitions/modules/modal.less new file mode 100644 index 0000000..e171222 --- /dev/null +++ b/semantic/src/definitions/modules/modal.less @@ -0,0 +1,583 @@ +/*! + * # Fomantic-UI - Modal + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + + +/******************************* + Theme +*******************************/ + +@type : 'module'; +@element : 'modal'; + +@import (multiple) '../../theme.config'; + +/******************************* + Modal +*******************************/ + +.ui.modal { + position: absolute; + display: none; + z-index: @zIndex; + text-align: left; + + background: @background; + border: @border; + box-shadow: @boxShadow; + transform-origin: @transformOrigin; + + flex: 0 0 auto; + + border-radius: @borderRadius; + user-select: text; + will-change: top, left, margin, transform, opacity; +} + +.ui.modal > :first-child:not(.icon):not(.dimmer), +.ui.modal > i.icon:first-child + *, +.ui.modal > .dimmer:first-child + *:not(.icon), +.ui.modal > .dimmer:first-child + i.icon + * { + border-top-left-radius: @borderRadius; + border-top-right-radius: @borderRadius; +} + +.ui.modal > :last-child { + border-bottom-left-radius: @borderRadius; + border-bottom-right-radius: @borderRadius; +} + +.ui.modal > .ui.dimmer { + border-radius: inherit; +} + +/******************************* + Content +*******************************/ + +/*-------------- + Close +---------------*/ + +.ui.modal > .close { + cursor: pointer; + position: absolute; + top: @closeTop; + right: @closeRight; + z-index: 1; + + opacity: @closeOpacity; + font-size: @closeSize; + color: @closeColor; + + width: @closeHitbox; + height: @closeHitbox; + padding: @closePadding; +} +.ui.modal > .close:hover { + opacity: 1; +} + +/*-------------- + Header +---------------*/ + +.ui.modal > .header { + display: block; + font-family: @headerFontFamily; + background: @headerBackground; + margin: @headerMargin; + padding: @headerPadding; + box-shadow: @headerBoxShadow; + + color: @headerColor; + border-bottom: @headerBorder; +} +.ui.modal > .header:not(.ui) { + font-size: @headerFontSize; + line-height: @headerLineHeight; + font-weight: @headerFontWeight; +} + +/*-------------- + Content +---------------*/ + +.ui.modal > .content { + display: block; + width: 100%; + font-size: @contentFontSize; + line-height: @contentLineHeight; + padding: @contentPadding; + background: @contentBackground; +} +.ui.modal > .image.content { + display: flex; + flex-direction: row; +} + +/* Image */ +.ui.modal > .content > .image { + display: block; + flex: 0 1 auto; + width: @imageWidth; + align-self: @imageVerticalAlign; + max-width: 100%; +} +.ui.modal > [class*="top aligned"] { + align-self: start; +} +.ui.modal > [class*="middle aligned"] { + align-self: center; +} +.ui.modal > [class*="stretched"] { + align-self: stretch; +} + +/* Description */ +.ui.modal > .content > .description { + display: block; + flex: 1 0 auto; + min-width: 0; + align-self: @descriptionVerticalAlign; +} + +.ui.modal > .content > i.icon + .description, +.ui.modal > .content > .image + .description { + flex: 0 1 auto; + min-width: @descriptionMinWidth; + width: @descriptionWidth; + padding-left: @descriptionDistance; +} + +/*rtl:ignore*/ +.ui.modal > .content > .image > i.icon { + margin: 0; + opacity: 1; + width: auto; + line-height: 1; + font-size: @imageIconSize; +} + +/*-------------- + Actions +---------------*/ + +.ui.modal > .actions { + background: @actionBackground; + padding: @actionPadding; + border-top: @actionBorder; + text-align: @actionAlign; +} +.ui.modal .actions > .button:not(.fluid) { + margin-left: @buttonDistance; +} +.ui.basic.modal > .actions { + border-top:none; +} + +/*------------------- + Responsive +--------------------*/ + +/* Modal Width */ +@media only screen and (max-width : @largestMobileScreen) { + .ui.modal:not(.fullscreen) { + width: @mobileWidth; + margin: @mobileMargin; + } +} +@media only screen and (min-width : @tabletBreakpoint) { + .ui.modal:not(.fullscreen) { + width: @tabletWidth; + margin: @tabletMargin; + } +} +@media only screen and (min-width : @computerBreakpoint) { + .ui.modal:not(.fullscreen) { + width: @computerWidth; + margin: @computerMargin; + } +} +@media only screen and (min-width : @largeMonitorBreakpoint) { + .ui.modal:not(.fullscreen) { + width: @largeMonitorWidth; + margin: @largeMonitorMargin; + } +} +@media only screen and (min-width : @widescreenMonitorBreakpoint) { + .ui.modal:not(.fullscreen) { + width: @widescreenMonitorWidth; + margin: @widescreenMonitorMargin; + } +} + +/* Tablet and Mobile */ +@media only screen and (max-width : @largestTabletScreen) { + .ui.modal > .header { + padding-right: @closeHitbox; + } + .ui.modal > .close { + top: @innerCloseTop; + right: @innerCloseRight; + color: @innerCloseColor; + } +} + +/* Mobile */ +@media only screen and (max-width : @largestMobileScreen) { + + .ui.modal > .header { + padding: @mobileHeaderPadding !important; + padding-right: @closeHitbox !important; + } + .ui.overlay.fullscreen.modal > .content.content.content { + min-height: @overlayFullscreenScrollingContentMaxHeightMobile; + } + .ui.overlay.fullscreen.modal > .scrolling.content.content.content { + max-height: @overlayFullscreenScrollingContentMaxHeightMobile; + } + .ui.modal > .content { + display: block; + padding: @mobileContentPadding !important; + } + .ui.modal > .close { + top: @mobileCloseTop !important; + right: @mobileCloseRight !important; + } + + /*rtl:ignore*/ + .ui.modal .image.content { + flex-direction: column; + } + .ui.modal > .content > .image { + display: block; + max-width: 100%; + margin: 0 auto !important; + text-align: center; + padding: @mobileImagePadding !important; + } + .ui.modal > .content > .image > i.icon { + font-size: @mobileImageIconSize; + text-align: center; + } + + /*rtl:ignore*/ + .ui.modal > .content > .description { + display: block; + width: 100% !important; + margin: 0 !important; + padding: @mobileDescriptionPadding !important; + box-shadow: none; + } + + /* Let Buttons Stack */ + .ui.modal > .actions { + padding: @mobileActionPadding !important; + } + .ui.modal .actions > .buttons, + .ui.modal .actions > .button { + margin-bottom: @mobileButtonDistance; + } +} + +/*-------------- + Coupling +---------------*/ + +.ui.inverted.dimmer > .ui.modal { + box-shadow: @invertedBoxShadow; +} + +/******************************* + Types +*******************************/ +& when (@variationModalBasic) { + .ui.basic.modal { + background-color: transparent; + border: none; + border-radius: 0; + box-shadow: none !important; + color: @basicModalColor; + } + .ui.basic.modal > .header, + .ui.basic.modal > .content, + .ui.basic.modal > .actions { + background-color: transparent; + } + .ui.basic.modal > .header { + color: @basicModalHeaderColor; + border-bottom: none; + } + .ui.basic.modal > .close { + top: @basicModalCloseTop; + right: @basicModalCloseRight; + color: @basicInnerCloseColor; + } + .ui.inverted.dimmer > .basic.modal { + color: @basicInvertedModalColor; + } + .ui.inverted.dimmer > .ui.basic.modal > .header { + color: @basicInvertedModalHeaderColor; + } +} + +& when (@variationModalLegacy) { + /* Resort to margin positioning if legacy */ + .ui.legacy.legacy.modal, + .ui.legacy.legacy.page.dimmer > .ui.modal { + left: 50% !important; + } + .ui.legacy.legacy.modal:not(.aligned), + .ui.legacy.legacy.page.dimmer > .ui.modal:not(.aligned) { + top: 50%; + } + .ui.legacy.legacy.page.dimmer > .ui.scrolling.modal:not(.aligned), + .ui.page.dimmer > .ui.scrolling.legacy.legacy.modal:not(.aligned), + .ui.top.aligned.legacy.legacy.page.dimmer > .ui.modal:not(.aligned), + .ui.top.aligned.dimmer > .ui.legacy.legacy.modal:not(.aligned) { + top: auto; + } + & when (@variationModalOverlay) { + .ui.legacy.overlay.fullscreen.modal { + margin-top: -@scrollingMargin !important; + } + } +} + +/******************************* + States +*******************************/ + +.ui.loading.modal { + display: block; + visibility: hidden; + z-index: @loadingZIndex; +} + +.ui.active.modal { + display: block; +} + +/******************************* + Variations +*******************************/ + +& when (@variationModalAligned) { + /*-------------- + Aligned + ---------------*/ + + .modals.dimmer .ui.top.aligned.modal { + top: @topAlignedMargin; + } + .modals.dimmer .ui.bottom.aligned.modal { + bottom: @bottomAlignedMargin; + } + + @media only screen and (max-width : @largestMobileScreen) { + .modals.dimmer .ui.top.aligned.modal { + top: @mobileTopAlignedMargin; + } + .modals.dimmer .ui.bottom.aligned.modal { + bottom: @mobileBottomAlignedMargin; + } + } +} + +& when (@variationModalScrolling) { + /*-------------- + Scrolling + ---------------*/ + + /* Scrolling Dimmer */ + .scrolling.dimmable.dimmed { + overflow: hidden; + } + .scrolling.dimmable > .dimmer { + justify-content: flex-start; + position: fixed; + } + .scrolling.dimmable.dimmed > .dimmer { + overflow: auto; + -webkit-overflow-scrolling: touch; + } + .modals.dimmer .ui.scrolling.modal:not(.fullscreen) { + margin: @scrollingMargin auto; + } +/* Fix for Firefox, Edge, IE11 */ +.modals.dimmer .ui.scrolling.modal:not([class*="overlay fullscreen"])::after { + content:'\00A0'; + position: absolute; + height: @scrollingMargin; +} + /* Undetached Scrolling */ + .scrolling.undetached.dimmable.dimmed { + overflow: auto; + -webkit-overflow-scrolling: touch; + } + .scrolling.undetached.dimmable.dimmed > .dimmer { + overflow: hidden; + } + .scrolling.undetached.dimmable .ui.scrolling.modal:not(.fullscreen) { + position: absolute; + left: 50%; + + } + + /* Scrolling Content */ + .ui.modal > .scrolling.content { + max-height: @scrollingContentMaxHeight; + overflow: auto; + } +} + +& when (@variationModalOverlay) { + .ui.overlay.fullscreen.modal > .content { + min-height: @overlayFullscreenScrollingContentMaxHeight; + } + .ui.overlay.fullscreen.modal > .scrolling.content { + max-height: @overlayFullscreenScrollingContentMaxHeight; + } +} + +& when (@variationModalFullscreen) or (@variationModalOverlay) or (@variationModalCloseInside) { + /*-------------- + Full Screen + ---------------*/ + + .ui.fullscreen.modal { + width: @fullScreenWidth; + left: @fullScreenOffset; + margin: @fullScreenMargin; + } + & when (@variationModalOverlay) { + .ui.overlay.fullscreen.modal { + width: 100%; + left: 0; + margin: 0 auto; + top: 0; + border-radius:0; + } + } + .ui.modal > .close.inside + .header, + .ui.fullscreen.modal > .header { + padding-right: @closeHitbox; + } + .ui.modal > .close.inside, + .ui.fullscreen.modal > .close { + top: @innerCloseTop; + right: @innerCloseRight; + color: @innerCloseColor; + } + & when (@variationModalBasic) { + .ui.basic.fullscreen.modal > .close { + color: @basicInnerCloseColor; + } + } +} +/*-------------- + Size +---------------*/ + +.ui.modal { + font-size: @medium; +} +& when not (@variationModalSizes = false) { + each(@variationModalSizes, { + @hs: @{value}HeaderSize; + @mw: @{value}MobileWidth; + @mm: @{value}MobileMargin; + @tw: @{value}TabletWidth; + @tm: @{value}TabletMargin; + @cw: @{value}ComputerWidth; + @cm: @{value}ComputerMargin; + @lw: @{value}LargeMonitorWidth; + @lm: @{value}LargeMonitorMargin; + @ww: @{value}WidescreenMonitorWidth; + @wm: @{value}WidescreenMonitorMargin; + .ui.@{value}.modal > .header:not(.ui) { + font-size: @@hs; + } + @media only screen and (max-width : @largestMobileScreen) { + .ui.@{value}.modal { + width: @@mw; + margin: @@mm; + } + } + @media only screen and (min-width : @tabletBreakpoint) { + .ui.@{value}.modal { + width: @@tw; + margin: @@tm; + } + } + @media only screen and (min-width : @computerBreakpoint) { + .ui.@{value}.modal { + width: @@cw; + margin: @@cm; + } + } + @media only screen and (min-width : @largeMonitorBreakpoint) { + .ui.@{value}.modal { + width: @@lw; + margin: @@lm; + } + } + @media only screen and (min-width : @widescreenMonitorBreakpoint) { + .ui.@{value}.modal { + width: @@ww; + margin: @@wm; + } + } + }) +} + +& when (@variationModalInverted) { + /***************************** + Inverted + *******************************/ + + .ui.inverted.modal { + background: @invertedBackground; + } + + .ui.inverted.modal > .header, + .ui.inverted.modal > .content { + background: @invertedBackground; + color: @invertedHeaderColor; + } + + .ui.inverted.modal > .actions { + background: @invertedActionBackground; + border-top: @invertedActionBorder; + color: @invertedActionColor; + } + + .ui.inverted.dimmer > .modal > .close { + color: @invertedDimmerCloseColor; + } + + + @media only screen and (max-width: @largestTabletScreen) { + .ui.dimmer .inverted.modal > .close { + color: @invertedCloseColor; + } + } + & when (@variationModalFullscreen) or (@variationModalCloseInside) { + .ui.inverted.modal > .close.inside, + .ui.inverted.fullscreen.modal > .close { + color: @invertedCloseColor; + } + } +} + + + + +.loadUIOverrides(); diff --git a/semantic/src/definitions/modules/nag.js b/semantic/src/definitions/modules/nag.js new file mode 100644 index 0000000..db88b77 --- /dev/null +++ b/semantic/src/definitions/modules/nag.js @@ -0,0 +1,492 @@ +/*! + * # Fomantic-UI - Nag + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +'use strict'; + +$.isFunction = $.isFunction || function(obj) { + return typeof obj === "function" && typeof obj.nodeType !== "number"; +}; + +window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.fn.nag = 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), + returnedValue + ; + $allModules + .each(function() { + var + settings = ( $.isPlainObject(parameters) ) + ? $.extend(true, {}, $.fn.nag.settings, parameters) + : $.extend({}, $.fn.nag.settings), + + selector = settings.selector, + error = settings.error, + namespace = settings.namespace, + + eventNamespace = '.' + namespace, + moduleNamespace = namespace + '-module', + + $module = $(this), + + $context = (settings.context) + ? $(settings.context) + : $('body'), + + element = this, + instance = $module.data(moduleNamespace), + + module + ; + module = { + + initialize: function() { + module.verbose('Initializing element'); + + $module + .on('click' + eventNamespace, selector.close, module.dismiss) + .data(moduleNamespace, module) + ; + + if(settings.detachable && $module.parent()[0] !== $context[0]) { + $module + .detach() + .prependTo($context) + ; + } + + if(settings.displayTime > 0) { + setTimeout(module.hide, settings.displayTime); + } + module.show(); + }, + + destroy: function() { + module.verbose('Destroying instance'); + $module + .removeData(moduleNamespace) + .off(eventNamespace) + ; + }, + + show: function() { + if( module.should.show() && !$module.is(':visible') ) { + module.debug('Showing nag', settings.animation.show); + if(settings.animation.show == 'fade') { + $module + .fadeIn(settings.duration, settings.easing) + ; + } + else { + $module + .slideDown(settings.duration, settings.easing) + ; + } + } + }, + + hide: function() { + module.debug('Showing nag', settings.animation.hide); + if(settings.animation.show == 'fade') { + $module + .fadeIn(settings.duration, settings.easing) + ; + } + else { + $module + .slideUp(settings.duration, settings.easing) + ; + } + }, + + onHide: function() { + module.debug('Removing nag', settings.animation.hide); + $module.remove(); + if (settings.onHide) { + settings.onHide(); + } + }, + + dismiss: function(event) { + if(settings.storageMethod) { + module.storage.set(settings.key, settings.value); + } + module.hide(); + event.stopImmediatePropagation(); + event.preventDefault(); + }, + + should: { + show: function() { + if(settings.persist) { + module.debug('Persistent nag is set, can show nag'); + return true; + } + if( module.storage.get(settings.key) != settings.value.toString() ) { + module.debug('Stored value is not set, can show nag', module.storage.get(settings.key)); + return true; + } + module.debug('Stored value is set, cannot show nag', module.storage.get(settings.key)); + return false; + } + }, + + get: { + storageOptions: function() { + var + options = {} + ; + if(settings.expires) { + options.expires = settings.expires; + } + if(settings.domain) { + options.domain = settings.domain; + } + if(settings.path) { + options.path = settings.path; + } + return options; + } + }, + + clear: function() { + module.storage.remove(settings.key); + }, + + storage: { + set: function(key, value) { + var + options = module.get.storageOptions() + ; + if(settings.storageMethod == 'localstorage' && window.localStorage !== undefined) { + window.localStorage.setItem(key, value); + module.debug('Value stored using local storage', key, value); + } + else if(settings.storageMethod == 'sessionstorage' && window.sessionStorage !== undefined) { + window.sessionStorage.setItem(key, value); + module.debug('Value stored using session storage', key, value); + } + else if($.cookie !== undefined) { + $.cookie(key, value, options); + module.debug('Value stored using cookie', key, value, options); + } + else { + module.error(error.noCookieStorage); + return; + } + }, + get: function(key, value) { + var + storedValue + ; + if(settings.storageMethod == 'localstorage' && window.localStorage !== undefined) { + storedValue = window.localStorage.getItem(key); + } + else if(settings.storageMethod == 'sessionstorage' && window.sessionStorage !== undefined) { + storedValue = window.sessionStorage.getItem(key); + } + // get by cookie + else if($.cookie !== undefined) { + storedValue = $.cookie(key); + } + else { + module.error(error.noCookieStorage); + } + if(storedValue == 'undefined' || storedValue == 'null' || storedValue === undefined || storedValue === null) { + storedValue = undefined; + } + return storedValue; + }, + remove: function(key) { + var + options = module.get.storageOptions() + ; + if(settings.storageMethod == 'localstorage' && window.localStorage !== undefined) { + window.localStorage.removeItem(key); + } + else if(settings.storageMethod == 'sessionstorage' && window.sessionStorage !== undefined) { + window.sessionStorage.removeItem(key); + } + // store by cookie + else if($.cookie !== undefined) { + $.removeCookie(key, options); + } + else { + module.error(error.noStorage); + } + } + }, + + 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(Array.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.nag.settings = { + + name : 'Nag', + + silent : false, + debug : false, + verbose : false, + performance : true, + + namespace : 'Nag', + + // allows cookie to be overridden + persist : false, + + // set to zero to require manually dismissal, otherwise hides on its own + displayTime : 0, + + animation : { + show : 'slide', + hide : 'slide' + }, + + context : false, + detachable : false, + + expires : 30, + domain : false, + path : '/', + + // type of storage to use + storageMethod : 'cookie', + + // value to store in dismissed localstorage/cookie + key : 'nag', + value : 'dismiss', + + error: { + noCookieStorage : '$.cookie is not included. A storage solution is required.', + noStorage : 'Neither $.cookie or store is defined. A storage solution is required for storing state', + method : 'The method you called is not defined.' + }, + + className : { + bottom : 'bottom', + fixed : 'fixed' + }, + + selector : { + close : '.close.icon' + }, + + speed : 500, + easing : 'easeOutQuad', + + onHide: function() {} + +}; + +// Adds easing +$.extend( $.easing, { + easeOutQuad: function (x, t, b, c, d) { + return -c *(t/=d)*(t-2) + b; + } +}); + +})( jQuery, window, document ); diff --git a/semantic/src/definitions/modules/nag.less b/semantic/src/definitions/modules/nag.less new file mode 100644 index 0000000..386e7fe --- /dev/null +++ b/semantic/src/definitions/modules/nag.less @@ -0,0 +1,158 @@ +/*! + * # Fomantic-UI - Nag + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + + +/******************************* + Theme +*******************************/ + +@type : 'module'; +@element : 'nag'; + +@import (multiple) '../../theme.config'; + +/******************************* + Nag +*******************************/ + +.ui.nag { + display: none; + opacity: @opacity; + position: @position; + + top: @top; + left: 0; + z-index: @zIndex; + + min-height: @minHeight; + width: @width; + + margin: @margin; + padding: @padding; + + background: @background; + box-shadow: @boxShadow; + + font-size: @fontSize; + text-align: @textAlign; + color: @color; + + border-radius: @topBorderRadius; + transition: @transition; +} + +a.ui.nag { + cursor: pointer; +} + +.ui.nag > .title { + display: inline-block; + margin: @titleMargin; + color: @titleColor; +} + + +.ui.nag > .close.icon { + cursor: pointer; + opacity: @closeOpacity; + + position: absolute; + top: @closeTop; + right: @closeRight; + + font-size: @closeSize; + + margin: @closeMargin; + color: @closeColor; + transition: @closeTransition; +} + + + +/******************************* + States +*******************************/ + +/* Hover */ +.ui.nag:hover { + background: @nagHoverBackground; + opacity: @nagHoverOpacity; +} + +.ui.nag .close:hover { + opacity: @closeHoverOpacity; +} + + +/******************************* + Variations +*******************************/ + + +/*-------------- + Static +---------------*/ + +.ui.overlay.nag { + position: absolute; + display: block; +} + +/*-------------- + Fixed +---------------*/ + +.ui.fixed.nag { + position: fixed; +} + +/*-------------- + Bottom +---------------*/ + +.ui.bottom.nags, +.ui.bottom.nag { + border-radius: @bottomBorderRadius; + top: auto; + bottom: @bottom; +} + +/*-------------- + White +---------------*/ + +.ui.inverted.nags .nag, +.ui.inverted.nag { + background-color: @invertedBackground; + color: @darkTextColor; +} +.ui.inverted.nags .nag .close, +.ui.inverted.nags .nag .title, +.ui.inverted.nag .close, +.ui.inverted.nag .title { + color: @lightTextColor; +} + + +/******************************* + Groups +*******************************/ + +.ui.nags .nag { + border-radius: @groupedBorderRadius !important; +} +.ui.nags .nag:last-child { + border-radius: @topBorderRadius; +} +.ui.bottom.nags .nag:last-child { + border-radius: @bottomBorderRadius; +} + +.loadUIOverrides(); diff --git a/semantic/src/definitions/modules/popup.js b/semantic/src/definitions/modules/popup.js new file mode 100644 index 0000000..d6b70e1 --- /dev/null +++ b/semantic/src/definitions/modules/popup.js @@ -0,0 +1,1541 @@ +/*! + * # Fomantic-UI - Popup + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +'use strict'; + +$.isFunction = $.isFunction || function(obj) { + return typeof obj === "function" && typeof obj.nodeType !== "number"; +}; + +window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.fn.popup = function(parameters) { + var + $allModules = $(this), + $document = $(document), + $window = $(window), + $body = $('body'), + + moduleSelector = $allModules.selector || '', + + clickEvent = ('ontouchstart' in document.documentElement) + ? 'touchstart' + : 'click', + + time = new Date().getTime(), + performance = [], + + query = arguments[0], + methodInvoked = (typeof query == 'string'), + queryArguments = [].slice.call(arguments, 1), + + returnedValue + ; + $allModules + .each(function() { + var + settings = ( $.isPlainObject(parameters) ) + ? $.extend(true, {}, $.fn.popup.settings, parameters) + : $.extend({}, $.fn.popup.settings), + + selector = settings.selector, + className = settings.className, + error = settings.error, + metadata = settings.metadata, + namespace = settings.namespace, + + eventNamespace = '.' + settings.namespace, + moduleNamespace = 'module-' + namespace, + + $module = $(this), + $context = $(settings.context), + $scrollContext = $(settings.scrollContext), + $boundary = $(settings.boundary), + $target = (settings.target) + ? $(settings.target) + : $module, + + $popup, + $offsetParent, + + searchDepth = 0, + triedPositions = false, + openedWithTouch = false, + + element = this, + instance = $module.data(moduleNamespace), + + documentObserver, + elementNamespace, + id, + module + ; + + module = { + + // binds events + initialize: function() { + module.debug('Initializing', $module); + module.createID(); + module.bind.events(); + if(!module.exists() && settings.preserve) { + module.create(); + } + if(settings.observeChanges) { + module.observeChanges(); + } + module.instantiate(); + }, + + instantiate: function() { + module.verbose('Storing instance', module); + instance = module; + $module + .data(moduleNamespace, instance) + ; + }, + + observeChanges: function() { + if('MutationObserver' in window) { + documentObserver = new MutationObserver(module.event.documentChanged); + documentObserver.observe(document, { + childList : true, + subtree : true + }); + module.debug('Setting up mutation observer', documentObserver); + } + }, + + refresh: function() { + if(settings.popup) { + $popup = $(settings.popup).eq(0); + } + else { + if(settings.inline) { + $popup = $target.nextAll(selector.popup).eq(0); + settings.popup = $popup; + } + } + if(settings.popup) { + $popup.addClass(className.loading); + $offsetParent = module.get.offsetParent(); + $popup.removeClass(className.loading); + if(settings.movePopup && module.has.popup() && module.get.offsetParent($popup)[0] !== $offsetParent[0]) { + module.debug('Moving popup to the same offset parent as target'); + $popup + .detach() + .appendTo($offsetParent) + ; + } + } + else { + $offsetParent = (settings.inline) + ? module.get.offsetParent($target) + : module.has.popup() + ? module.get.offsetParent($popup) + : $body + ; + } + if( $offsetParent.is('html') && $offsetParent[0] !== $body[0] ) { + module.debug('Setting page as offset parent'); + $offsetParent = $body; + } + if( module.get.variation() ) { + module.set.variation(); + } + }, + + reposition: function() { + module.refresh(); + module.set.position(); + }, + + destroy: function() { + module.debug('Destroying previous module'); + if(documentObserver) { + documentObserver.disconnect(); + } + // remove element only if was created dynamically + if($popup && !settings.preserve) { + module.removePopup(); + } + // clear all timeouts + clearTimeout(module.hideTimer); + clearTimeout(module.showTimer); + // remove events + module.unbind.close(); + module.unbind.events(); + $module + .removeData(moduleNamespace) + ; + }, + + event: { + start: function(event) { + var + delay = ($.isPlainObject(settings.delay)) + ? settings.delay.show + : settings.delay + ; + clearTimeout(module.hideTimer); + if(!openedWithTouch || (openedWithTouch && settings.addTouchEvents) ) { + module.showTimer = setTimeout(module.show, delay); + } + }, + end: function() { + var + delay = ($.isPlainObject(settings.delay)) + ? settings.delay.hide + : settings.delay + ; + clearTimeout(module.showTimer); + module.hideTimer = setTimeout(module.hide, delay); + }, + touchstart: function(event) { + openedWithTouch = true; + if(settings.addTouchEvents) { + module.show(); + } + }, + resize: function() { + if( module.is.visible() ) { + module.set.position(); + } + }, + documentChanged: function(mutations) { + [].forEach.call(mutations, function(mutation) { + if(mutation.removedNodes) { + [].forEach.call(mutation.removedNodes, function(node) { + if(node == element || $(node).find(element).length > 0) { + module.debug('Element removed from DOM, tearing down events'); + module.destroy(); + } + }); + } + }); + }, + hideGracefully: function(event) { + var + $target = $(event.target), + isInDOM = $.contains(document.documentElement, event.target), + inPopup = ($target.closest(selector.popup).length > 0) + ; + // don't close on clicks inside popup + if(event && !inPopup && isInDOM) { + module.debug('Click occurred outside popup hiding popup'); + module.hide(); + } + else { + module.debug('Click was inside popup, keeping popup open'); + } + } + }, + + // generates popup html from metadata + create: function() { + var + html = module.get.html(), + title = module.get.title(), + content = module.get.content() + ; + + if(html || content || title) { + module.debug('Creating pop-up html'); + if(!html) { + html = settings.templates.popup({ + title : title, + content : content + }); + } + $popup = $('<div/>') + .addClass(className.popup) + .data(metadata.activator, $module) + .html(html) + ; + if(settings.inline) { + module.verbose('Inserting popup element inline', $popup); + $popup + .insertAfter($module) + ; + } + else { + module.verbose('Appending popup element to body', $popup); + $popup + .appendTo( $context ) + ; + } + module.refresh(); + module.set.variation(); + + if(settings.hoverable) { + module.bind.popup(); + } + settings.onCreate.call($popup, element); + } + else if(settings.popup) { + $(settings.popup).data(metadata.activator, $module); + module.verbose('Used popup specified in settings'); + module.refresh(); + if(settings.hoverable) { + module.bind.popup(); + } + } + else if($target.next(selector.popup).length !== 0) { + module.verbose('Pre-existing popup found'); + settings.inline = true; + settings.popup = $target.next(selector.popup).data(metadata.activator, $module); + module.refresh(); + if(settings.hoverable) { + module.bind.popup(); + } + } + else { + module.debug('No content specified skipping display', element); + } + }, + + createID: function() { + id = (Math.random().toString(16) + '000000000').substr(2, 8); + elementNamespace = '.' + id; + module.verbose('Creating unique id for element', id); + }, + + // determines popup state + toggle: function() { + module.debug('Toggling pop-up'); + if( module.is.hidden() ) { + module.debug('Popup is hidden, showing pop-up'); + module.unbind.close(); + module.show(); + } + else { + module.debug('Popup is visible, hiding pop-up'); + module.hide(); + } + }, + + show: function(callback) { + callback = callback || function(){}; + module.debug('Showing pop-up', settings.transition); + if(module.is.hidden() && !( module.is.active() && module.is.dropdown()) ) { + if( !module.exists() ) { + module.create(); + } + if(settings.onShow.call($popup, element) === false) { + module.debug('onShow callback returned false, cancelling popup animation'); + return; + } + else if(!settings.preserve && !settings.popup) { + module.refresh(); + } + if( $popup && module.set.position() ) { + module.save.conditions(); + if(settings.exclusive) { + module.hideAll(); + } + module.animate.show(callback); + } + } + }, + + + hide: function(callback) { + callback = callback || function(){}; + if( module.is.visible() || module.is.animating() ) { + if(settings.onHide.call($popup, element) === false) { + module.debug('onHide callback returned false, cancelling popup animation'); + return; + } + module.remove.visible(); + module.unbind.close(); + module.restore.conditions(); + module.animate.hide(callback); + } + }, + + hideAll: function() { + $(selector.popup) + .filter('.' + className.popupVisible) + .each(function() { + $(this) + .data(metadata.activator) + .popup('hide') + ; + }) + ; + }, + exists: function() { + if(!$popup) { + return false; + } + if(settings.inline || settings.popup) { + return ( module.has.popup() ); + } + else { + return ( $popup.closest($context).length >= 1 ) + ? true + : false + ; + } + }, + + removePopup: function() { + if( module.has.popup() && !settings.popup) { + module.debug('Removing popup', $popup); + $popup.remove(); + $popup = undefined; + settings.onRemove.call($popup, element); + } + }, + + save: { + conditions: function() { + module.cache = { + title: $module.attr('title') + }; + if (module.cache.title) { + $module.removeAttr('title'); + } + module.verbose('Saving original attributes', module.cache.title); + } + }, + restore: { + conditions: function() { + if(module.cache && module.cache.title) { + $module.attr('title', module.cache.title); + module.verbose('Restoring original attributes', module.cache.title); + } + return true; + } + }, + supports: { + svg: function() { + return (typeof SVGGraphicsElement !== 'undefined'); + } + }, + animate: { + show: function(callback) { + callback = $.isFunction(callback) ? callback : function(){}; + if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { + module.set.visible(); + $popup + .transition({ + animation : settings.transition + ' in', + queue : false, + debug : settings.debug, + verbose : settings.verbose, + duration : settings.duration, + onComplete : function() { + module.bind.close(); + callback.call($popup, element); + settings.onVisible.call($popup, element); + } + }) + ; + } + else { + module.error(error.noTransition); + } + }, + hide: function(callback) { + callback = $.isFunction(callback) ? callback : function(){}; + module.debug('Hiding pop-up'); + if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { + $popup + .transition({ + animation : settings.transition + ' out', + queue : false, + duration : settings.duration, + debug : settings.debug, + verbose : settings.verbose, + onComplete : function() { + module.reset(); + callback.call($popup, element); + settings.onHidden.call($popup, element); + } + }) + ; + } + else { + module.error(error.noTransition); + } + } + }, + + change: { + content: function(html) { + $popup.html(html); + } + }, + + get: { + html: function() { + $module.removeData(metadata.html); + return $module.data(metadata.html) || settings.html; + }, + title: function() { + $module.removeData(metadata.title); + return $module.data(metadata.title) || settings.title; + }, + content: function() { + $module.removeData(metadata.content); + return $module.data(metadata.content) || settings.content || $module.attr('title'); + }, + variation: function() { + $module.removeData(metadata.variation); + return $module.data(metadata.variation) || settings.variation; + }, + popup: function() { + return $popup; + }, + popupOffset: function() { + return $popup.offset(); + }, + calculations: function() { + var + $popupOffsetParent = module.get.offsetParent($popup), + targetElement = $target[0], + isWindow = ($boundary[0] == window), + targetOffset = $target.offset(), + parentOffset = settings.inline || (settings.popup && settings.movePopup) + ? $target.offsetParent().offset() + : { top: 0, left: 0 }, + screenPosition = (isWindow) + ? { top: 0, left: 0 } + : $boundary.offset(), + calculations = {}, + scroll = (isWindow) + ? { top: $window.scrollTop(), left: $window.scrollLeft() } + : { top: 0, left: 0}, + screen + ; + calculations = { + // element which is launching popup + target : { + element : $target[0], + width : $target.outerWidth(), + height : $target.outerHeight(), + top : targetOffset.top - parentOffset.top, + left : targetOffset.left - parentOffset.left, + margin : {} + }, + // popup itself + popup : { + width : $popup.outerWidth(), + height : $popup.outerHeight() + }, + // offset container (or 3d context) + parent : { + width : $offsetParent.outerWidth(), + height : $offsetParent.outerHeight() + }, + // screen boundaries + screen : { + top : screenPosition.top, + left : screenPosition.left, + scroll: { + top : scroll.top, + left : scroll.left + }, + width : $boundary.width(), + height : $boundary.height() + } + }; + + // if popup offset context is not same as target, then adjust calculations + if($popupOffsetParent.get(0) !== $offsetParent.get(0)) { + var + popupOffset = $popupOffsetParent.offset() + ; + calculations.target.top -= popupOffset.top; + calculations.target.left -= popupOffset.left; + calculations.parent.width = $popupOffsetParent.outerWidth(); + calculations.parent.height = $popupOffsetParent.outerHeight(); + } + + // add in container calcs if fluid + if( settings.setFluidWidth && module.is.fluid() ) { + calculations.container = { + width: $popup.parent().outerWidth() + }; + calculations.popup.width = calculations.container.width; + } + + // add in margins if inline + calculations.target.margin.top = (settings.inline) + ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-top'), 10) + : 0 + ; + calculations.target.margin.left = (settings.inline) + ? module.is.rtl() + ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-right'), 10) + : parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-left'), 10) + : 0 + ; + // calculate screen boundaries + screen = calculations.screen; + calculations.boundary = { + top : screen.top + screen.scroll.top, + bottom : screen.top + screen.scroll.top + screen.height, + left : screen.left + screen.scroll.left, + right : screen.left + screen.scroll.left + screen.width + }; + return calculations; + }, + id: function() { + return id; + }, + startEvent: function() { + if(settings.on == 'hover') { + return 'mouseenter'; + } + else if(settings.on == 'focus') { + return 'focus'; + } + return false; + }, + scrollEvent: function() { + return 'scroll'; + }, + endEvent: function() { + if(settings.on == 'hover') { + return 'mouseleave'; + } + else if(settings.on == 'focus') { + return 'blur'; + } + return false; + }, + distanceFromBoundary: function(offset, calculations) { + var + distanceFromBoundary = {}, + popup, + boundary + ; + calculations = calculations || module.get.calculations(); + + // shorthand + popup = calculations.popup; + boundary = calculations.boundary; + + if(offset) { + distanceFromBoundary = { + top : (offset.top - boundary.top), + left : (offset.left - boundary.left), + right : (boundary.right - (offset.left + popup.width) ), + bottom : (boundary.bottom - (offset.top + popup.height) ) + }; + module.verbose('Distance from boundaries determined', offset, distanceFromBoundary); + } + return distanceFromBoundary; + }, + offsetParent: function($element) { + var + element = ($element !== undefined) + ? $element[0] + : $target[0], + parentNode = element.parentNode, + $node = $(parentNode) + ; + if(parentNode) { + var + is2D = ($node.css('transform') === 'none'), + isStatic = ($node.css('position') === 'static'), + isBody = $node.is('body') + ; + while(parentNode && !isBody && isStatic && is2D) { + parentNode = parentNode.parentNode; + $node = $(parentNode); + is2D = ($node.css('transform') === 'none'); + isStatic = ($node.css('position') === 'static'); + isBody = $node.is('body'); + } + } + return ($node && $node.length > 0) + ? $node + : $() + ; + }, + positions: function() { + return { + 'top left' : false, + 'top center' : false, + 'top right' : false, + 'bottom left' : false, + 'bottom center' : false, + 'bottom right' : false, + 'left center' : false, + 'right center' : false + }; + }, + nextPosition: function(position) { + var + positions = position.split(' '), + verticalPosition = positions[0], + horizontalPosition = positions[1], + opposite = { + top : 'bottom', + bottom : 'top', + left : 'right', + right : 'left' + }, + adjacent = { + left : 'center', + center : 'right', + right : 'left' + }, + backup = { + 'top left' : 'top center', + 'top center' : 'top right', + 'top right' : 'right center', + 'right center' : 'bottom right', + 'bottom right' : 'bottom center', + 'bottom center' : 'bottom left', + 'bottom left' : 'left center', + 'left center' : 'top left' + }, + adjacentsAvailable = (verticalPosition == 'top' || verticalPosition == 'bottom'), + oppositeTried = false, + adjacentTried = false, + nextPosition = false + ; + if(!triedPositions) { + module.verbose('All available positions available'); + triedPositions = module.get.positions(); + } + + module.debug('Recording last position tried', position); + triedPositions[position] = true; + + if(settings.prefer === 'opposite') { + nextPosition = [opposite[verticalPosition], horizontalPosition]; + nextPosition = nextPosition.join(' '); + oppositeTried = (triedPositions[nextPosition] === true); + module.debug('Trying opposite strategy', nextPosition); + } + if((settings.prefer === 'adjacent') && adjacentsAvailable ) { + nextPosition = [verticalPosition, adjacent[horizontalPosition]]; + nextPosition = nextPosition.join(' '); + adjacentTried = (triedPositions[nextPosition] === true); + module.debug('Trying adjacent strategy', nextPosition); + } + if(adjacentTried || oppositeTried) { + module.debug('Using backup position', nextPosition); + nextPosition = backup[position]; + } + return nextPosition; + } + }, + + set: { + position: function(position, calculations) { + + // exit conditions + if($target.length === 0 || $popup.length === 0) { + module.error(error.notFound); + return; + } + var + offset, + distanceAway, + target, + popup, + parent, + positioning, + popupOffset, + distanceFromBoundary + ; + + calculations = calculations || module.get.calculations(); + position = position || $module.data(metadata.position) || settings.position; + + offset = $module.data(metadata.offset) || settings.offset; + distanceAway = settings.distanceAway; + + // shorthand + target = calculations.target; + popup = calculations.popup; + parent = calculations.parent; + + if(module.should.centerArrow(calculations)) { + module.verbose('Adjusting offset to center arrow on small target element'); + if(position == 'top left' || position == 'bottom left') { + offset += (target.width / 2); + offset -= settings.arrowPixelsFromEdge; + } + if(position == 'top right' || position == 'bottom right') { + offset -= (target.width / 2); + offset += settings.arrowPixelsFromEdge; + } + } + + if(target.width === 0 && target.height === 0 && !module.is.svg(target.element)) { + module.debug('Popup target is hidden, no action taken'); + return false; + } + + if(settings.inline) { + module.debug('Adding margin to calculation', target.margin); + if(position == 'left center' || position == 'right center') { + offset += target.margin.top; + distanceAway += -target.margin.left; + } + else if (position == 'top left' || position == 'top center' || position == 'top right') { + offset += target.margin.left; + distanceAway -= target.margin.top; + } + else { + offset += target.margin.left; + distanceAway += target.margin.top; + } + } + + module.debug('Determining popup position from calculations', position, calculations); + + if (module.is.rtl()) { + position = position.replace(/left|right/g, function (match) { + return (match == 'left') + ? 'right' + : 'left' + ; + }); + module.debug('RTL: Popup position updated', position); + } + + // if last attempt use specified last resort position + if(searchDepth == settings.maxSearchDepth && typeof settings.lastResort === 'string') { + position = settings.lastResort; + } + + switch (position) { + case 'top left': + positioning = { + top : 'auto', + bottom : parent.height - target.top + distanceAway, + left : target.left + offset, + right : 'auto' + }; + break; + case 'top center': + positioning = { + bottom : parent.height - target.top + distanceAway, + left : target.left + (target.width / 2) - (popup.width / 2) + offset, + top : 'auto', + right : 'auto' + }; + break; + case 'top right': + positioning = { + bottom : parent.height - target.top + distanceAway, + right : parent.width - target.left - target.width - offset, + top : 'auto', + left : 'auto' + }; + break; + case 'left center': + positioning = { + top : target.top + (target.height / 2) - (popup.height / 2) + offset, + right : parent.width - target.left + distanceAway, + left : 'auto', + bottom : 'auto' + }; + break; + case 'right center': + positioning = { + top : target.top + (target.height / 2) - (popup.height / 2) + offset, + left : target.left + target.width + distanceAway, + bottom : 'auto', + right : 'auto' + }; + break; + case 'bottom left': + positioning = { + top : target.top + target.height + distanceAway, + left : target.left + offset, + bottom : 'auto', + right : 'auto' + }; + break; + case 'bottom center': + positioning = { + top : target.top + target.height + distanceAway, + left : target.left + (target.width / 2) - (popup.width / 2) + offset, + bottom : 'auto', + right : 'auto' + }; + break; + case 'bottom right': + positioning = { + top : target.top + target.height + distanceAway, + right : parent.width - target.left - target.width - offset, + left : 'auto', + bottom : 'auto' + }; + break; + } + if(positioning === undefined) { + module.error(error.invalidPosition, position); + } + + module.debug('Calculated popup positioning values', positioning); + + // tentatively place on stage + $popup + .css(positioning) + .removeClass(className.position) + .addClass(position) + .addClass(className.loading) + ; + + popupOffset = module.get.popupOffset(); + + // see if any boundaries are surpassed with this tentative position + distanceFromBoundary = module.get.distanceFromBoundary(popupOffset, calculations); + + if(!settings.forcePosition && module.is.offstage(distanceFromBoundary, position) ) { + module.debug('Position is outside viewport', position); + if(searchDepth < settings.maxSearchDepth) { + searchDepth++; + position = module.get.nextPosition(position); + module.debug('Trying new position', position); + return ($popup) + ? module.set.position(position, calculations) + : false + ; + } + else { + if(settings.lastResort) { + module.debug('No position found, showing with last position'); + } + else { + module.debug('Popup could not find a position to display', $popup); + module.error(error.cannotPlace, element); + module.remove.attempts(); + module.remove.loading(); + module.reset(); + settings.onUnplaceable.call($popup, element); + return false; + } + } + } + module.debug('Position is on stage', position); + module.remove.attempts(); + module.remove.loading(); + if( settings.setFluidWidth && module.is.fluid() ) { + module.set.fluidWidth(calculations); + } + return true; + }, + + fluidWidth: function(calculations) { + calculations = calculations || module.get.calculations(); + module.debug('Automatically setting element width to parent width', calculations.parent.width); + $popup.css('width', calculations.container.width); + }, + + variation: function(variation) { + variation = variation || module.get.variation(); + if(variation && module.has.popup() ) { + module.verbose('Adding variation to popup', variation); + $popup.addClass(variation); + } + }, + + visible: function() { + $module.addClass(className.visible); + } + }, + + remove: { + loading: function() { + $popup.removeClass(className.loading); + }, + variation: function(variation) { + variation = variation || module.get.variation(); + if(variation) { + module.verbose('Removing variation', variation); + $popup.removeClass(variation); + } + }, + visible: function() { + $module.removeClass(className.visible); + }, + attempts: function() { + module.verbose('Resetting all searched positions'); + searchDepth = 0; + triedPositions = false; + } + }, + + bind: { + events: function() { + module.debug('Binding popup events to module'); + if(settings.on == 'click') { + $module + .on(clickEvent + eventNamespace, module.toggle) + ; + } + if(settings.on == 'hover') { + $module + .on('touchstart' + eventNamespace, module.event.touchstart) + ; + } + if( module.get.startEvent() ) { + $module + .on(module.get.startEvent() + eventNamespace, module.event.start) + .on(module.get.endEvent() + eventNamespace, module.event.end) + ; + } + if(settings.target) { + module.debug('Target set to element', $target); + } + $window.on('resize' + elementNamespace, module.event.resize); + }, + popup: function() { + module.verbose('Allowing hover events on popup to prevent closing'); + if( $popup && module.has.popup() ) { + $popup + .on('mouseenter' + eventNamespace, module.event.start) + .on('mouseleave' + eventNamespace, module.event.end) + ; + } + }, + close: function() { + if(settings.hideOnScroll === true || (settings.hideOnScroll == 'auto' && settings.on != 'click')) { + module.bind.closeOnScroll(); + } + if(module.is.closable()) { + module.bind.clickaway(); + } + else if(settings.on == 'hover' && openedWithTouch) { + module.bind.touchClose(); + } + }, + closeOnScroll: function() { + module.verbose('Binding scroll close event to document'); + $scrollContext + .one(module.get.scrollEvent() + elementNamespace, module.event.hideGracefully) + ; + }, + touchClose: function() { + module.verbose('Binding popup touchclose event to document'); + $document + .on('touchstart' + elementNamespace, function(event) { + module.verbose('Touched away from popup'); + module.event.hideGracefully.call(element, event); + }) + ; + }, + clickaway: function() { + module.verbose('Binding popup close event to document'); + $document + .on(clickEvent + elementNamespace, function(event) { + module.verbose('Clicked away from popup'); + module.event.hideGracefully.call(element, event); + }) + ; + } + }, + + unbind: { + events: function() { + $window + .off(elementNamespace) + ; + $module + .off(eventNamespace) + ; + }, + close: function() { + $document + .off(elementNamespace) + ; + $scrollContext + .off(elementNamespace) + ; + }, + }, + + has: { + popup: function() { + return ($popup && $popup.length > 0); + } + }, + + should: { + centerArrow: function(calculations) { + return !module.is.basic() && calculations.target.width <= (settings.arrowPixelsFromEdge * 2); + }, + }, + + is: { + closable: function() { + if(settings.closable == 'auto') { + if(settings.on == 'hover') { + return false; + } + return true; + } + return settings.closable; + }, + offstage: function(distanceFromBoundary, position) { + var + offstage = [] + ; + // return boundaries that have been surpassed + $.each(distanceFromBoundary, function(direction, distance) { + if(distance < -settings.jitter) { + module.debug('Position exceeds allowable distance from edge', direction, distance, position); + offstage.push(direction); + } + }); + if(offstage.length > 0) { + return true; + } + else { + return false; + } + }, + svg: function(element) { + return module.supports.svg() && (element instanceof SVGGraphicsElement); + }, + basic: function() { + return $module.hasClass(className.basic); + }, + active: function() { + return $module.hasClass(className.active); + }, + animating: function() { + return ($popup !== undefined && $popup.hasClass(className.animating) ); + }, + fluid: function() { + return ($popup !== undefined && $popup.hasClass(className.fluid)); + }, + visible: function() { + return ($popup !== undefined && $popup.hasClass(className.popupVisible)); + }, + dropdown: function() { + return $module.hasClass(className.dropdown); + }, + hidden: function() { + return !module.is.visible(); + }, + rtl: function () { + return $module.attr('dir') === 'rtl' || $module.css('direction') === 'rtl'; + } + }, + + reset: function() { + module.remove.visible(); + if(settings.preserve) { + if($.fn.transition !== undefined) { + $popup + .transition('remove transition') + ; + } + } + else { + module.removePopup(); + } + }, + + setting: function(name, value) { + if( $.isPlainObject(name) ) { + $.extend(true, settings, name); + } + else if(value !== undefined) { + 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 { + return false; + } + }); + } + if ( $.isFunction( found ) ) { + response = found.apply(context, passedArguments); + } + else if(found !== undefined) { + response = found; + } + if(Array.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.popup.settings = { + + name : 'Popup', + + // module settings + silent : false, + debug : false, + verbose : false, + performance : true, + namespace : 'popup', + + // whether it should use dom mutation observers + observeChanges : true, + + // callback only when element added to dom + onCreate : function(){}, + + // callback before element removed from dom + onRemove : function(){}, + + // callback before show animation + onShow : function(){}, + + // callback after show animation + onVisible : function(){}, + + // callback before hide animation + onHide : function(){}, + + // callback when popup cannot be positioned in visible screen + onUnplaceable : function(){}, + + // callback after hide animation + onHidden : function(){}, + + // when to show popup + on : 'hover', + + // element to use to determine if popup is out of boundary + boundary : window, + + // whether to add touchstart events when using hover + addTouchEvents : true, + + // default position relative to element + position : 'top left', + + // if given position should be used regardless if popup fits + forcePosition : false, + + // name of variation to use + variation : '', + + // whether popup should be moved to context + movePopup : true, + + // element which popup should be relative to + target : false, + + // jq selector or element that should be used as popup + popup : false, + + // popup should remain inline next to activator + inline : false, + + // popup should be removed from page on hide + preserve : false, + + // popup should not close when being hovered on + hoverable : false, + + // explicitly set content + content : false, + + // explicitly set html + html : false, + + // explicitly set title + title : false, + + // whether automatically close on clickaway when on click + closable : true, + + // automatically hide on scroll + hideOnScroll : 'auto', + + // hide other popups on show + exclusive : false, + + // context to attach popups + context : 'body', + + // context for binding scroll events + scrollContext : window, + + // position to prefer when calculating new position + prefer : 'opposite', + + // specify position to appear even if it doesn't fit + lastResort : false, + + // number of pixels from edge of popup to pointing arrow center (used from centering) + arrowPixelsFromEdge: 20, + + // delay used to prevent accidental refiring of animations due to user error + delay : { + show : 50, + hide : 70 + }, + + // whether fluid variation should assign width explicitly + setFluidWidth : true, + + // transition settings + duration : 200, + transition : 'scale', + + // distance away from activating element in px + distanceAway : 0, + + // number of pixels an element is allowed to be "offstage" for a position to be chosen (allows for rounding) + jitter : 2, + + // offset on aligning axis from calculated position + offset : 0, + + // maximum times to look for a position before failing (9 positions total) + maxSearchDepth : 15, + + error: { + invalidPosition : 'The position you specified is not a valid position', + cannotPlace : 'Popup does not fit within the boundaries of the viewport', + method : 'The method you called is not defined.', + noTransition : 'This module requires ui transitions <https://github.com/Semantic-Org/UI-Transition>', + notFound : 'The target or popup you specified does not exist on the page' + }, + + metadata: { + activator : 'activator', + content : 'content', + html : 'html', + offset : 'offset', + position : 'position', + title : 'title', + variation : 'variation' + }, + + className : { + active : 'active', + basic : 'basic', + animating : 'animating', + dropdown : 'dropdown', + fluid : 'fluid', + loading : 'loading', + popup : 'ui popup', + position : 'top left center bottom right', + visible : 'visible', + popupVisible : 'visible' + }, + + selector : { + popup : '.ui.popup' + }, + + templates: { + escape: function(string) { + var + badChars = /[<>"'`]/g, + shouldEscape = /[&<>"'`]/, + escape = { + "<": "<", + ">": ">", + '"': """, + "'": "'", + "`": "`" + }, + escapedChar = function(chr) { + return escape[chr]; + } + ; + if(shouldEscape.test(string)) { + string = string.replace(/&(?![a-z0-9#]{1,6};)/, "&"); + return string.replace(badChars, escapedChar); + } + return string; + }, + popup: function(text) { + var + html = '', + escape = $.fn.popup.settings.templates.escape + ; + if(typeof text !== undefined) { + if(typeof text.title !== undefined && text.title) { + text.title = escape(text.title); + html += '<div class="header">' + text.title + '</div>'; + } + if(typeof text.content !== undefined && text.content) { + text.content = escape(text.content); + html += '<div class="content">' + text.content + '</div>'; + } + } + return html; + } + } + +}; + + +})( jQuery, window, document ); diff --git a/semantic/src/definitions/modules/popup.less b/semantic/src/definitions/modules/popup.less new file mode 100644 index 0000000..7d08569 --- /dev/null +++ b/semantic/src/definitions/modules/popup.less @@ -0,0 +1,841 @@ +/*! + * # Fomantic-UI - Popup + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + + +/******************************* + Theme +*******************************/ + +@type : 'module'; +@element : 'popup'; + +@import (multiple) '../../theme.config'; + + +/******************************* + Popup +*******************************/ + +.ui.popup { + display: none; + position: absolute; + top: 0; + right: 0; + + /* Fixes content being squished when inline (moz only) */ + min-width: min-content; + z-index: @zIndex; + + border: @border; + line-height: @lineHeight; + max-width: @maxWidth; + background: @background; + + padding: @verticalPadding @horizontalPadding; + font-weight: @fontWeight; + font-style: @fontStyle; + color: @color; + + border-radius: @borderRadius; + box-shadow: @boxShadow; +} +.ui.popup > .header { + padding: 0; + + font-family: @headerFont; + font-size: @headerFontSize; + line-height: @headerLineHeight; + font-weight: @headerFontWeight; +} +.ui.popup > .header + .content { + padding-top: @headerDistance; +} + +.ui.popup:before { + position: absolute; + content: ''; + width: @arrowSize; + height: @arrowSize; + + background: @arrowBackground; + transform: rotate(45deg); + + z-index: @arrowZIndex; + box-shadow: @arrowBoxShadow; +} + +/******************************* + Types +*******************************/ + +& when (@variationPopupTooltip) { + /*-------------- + Tooltip + ---------------*/ + + /* Content */ + [data-tooltip] { + position: relative; + } + + /* Arrow */ + [data-tooltip]:before { + pointer-events: none; + position: absolute; + content: ''; + font-size: @medium; + width: @arrowSize; + height: @arrowSize; + + background: @tooltipArrowBackground; + transform: rotate(45deg); + + z-index: @arrowZIndex; + box-shadow: @tooltipArrowBoxShadow; + } + + /* Popup */ + [data-tooltip]:after { + pointer-events: none; + content: attr(data-tooltip); + position: absolute; + text-transform: none; + text-align: left; + text-shadow: none; + white-space: nowrap; + + font-size: @tooltipFontSize; + + border: @tooltipBorder; + line-height: @tooltipLineHeight; + max-width: @tooltipMaxWidth; + background: @tooltipBackground; + + padding: @tooltipPadding; + font-weight: @tooltipFontWeight; + font-style: @tooltipFontStyle; + color: @tooltipColor; + + border-radius: @tooltipBorderRadius; + box-shadow: @tooltipBoxShadow; + z-index: @tooltipZIndex; + } + + /* Default Position (Top Center) */ + [data-tooltip]:not([data-position]):before { + top: auto; + right: auto; + bottom: 100%; + left: 50%; + background: @tooltipArrowBottomBackground; + margin-left: @tooltipArrowHorizontalOffset; + margin-bottom: -@tooltipArrowVerticalOffset; + } + [data-tooltip]:not([data-position]):after { + left: 50%; + transform: translateX(-50%); + bottom: 100%; + margin-bottom: @tooltipDistanceAway; + } + + /* Animation */ + [data-tooltip]:before, + [data-tooltip]:after { + pointer-events: none; + visibility: hidden; + opacity: 0; + transition: + transform @tooltipDuration @tooltipEasing, + opacity @tooltipDuration @tooltipEasing + ; + } + [data-tooltip]:before { + transform: rotate(45deg) scale(0) !important; + transform-origin: center top; + } + [data-tooltip]:after { + transform-origin: center bottom; + } + [data-tooltip]:hover:before, + [data-tooltip]:hover:after { + visibility: visible; + pointer-events: auto; + opacity: 1; + } + [data-tooltip]:hover:before { + transform: rotate(45deg) scale(1) !important; + } + + /* Animation Position */ + [data-tooltip]:after, + [data-tooltip][data-position="top center"]:after, + [data-tooltip][data-position="bottom center"]:after { + transform: translateX(-50%) scale(0) !important; + } + [data-tooltip]:hover:after, + [data-tooltip][data-position="bottom center"]:hover:after { + transform: translateX(-50%) scale(1) !important; + } + [data-tooltip][data-position="left center"]:after, + [data-tooltip][data-position="right center"]:after { + transform: translateY(-50%) scale(0) !important; + } + [data-tooltip][data-position="left center"]:hover:after, + [data-tooltip][data-position="right center"]:hover:after { + transform: translateY(-50%) scale(1) !important; + -moz-transform: translateY(-50%) scale(1.0001) !important; + } + [data-tooltip][data-position="top left"]:after, + [data-tooltip][data-position="top right"]:after, + [data-tooltip][data-position="bottom left"]:after, + [data-tooltip][data-position="bottom right"]:after { + transform: scale(0) !important; + } + [data-tooltip][data-position="top left"]:hover:after, + [data-tooltip][data-position="top right"]:hover:after, + [data-tooltip][data-position="bottom left"]:hover:after, + [data-tooltip][data-position="bottom right"]:hover:after { + transform: scale(1) !important; + } + & when (@variationPopupFixed) { + [data-tooltip][data-variation~="fixed"]:after { + white-space: normal; + width: @maxWidth; + } + [data-tooltip][data-variation*="wide fixed"]:after { + width: @wideWidth; + } + [data-tooltip][data-variation*="very wide fixed"]:after { + width: @veryWideWidth; + } + @media only screen and (max-width: @largestMobileScreen) { + [data-tooltip][data-variation~="fixed"]:after { + width: @maxWidth; + } + } + } + & when (@variationPopupInverted) { + /*-------------- + Inverted + ---------------*/ + + /* Arrow */ + [data-tooltip][data-inverted]:before { + box-shadow: none !important; + } + + /* Arrow Position */ + [data-tooltip][data-inverted]:before { + background: @invertedArrowBottomBackground; + } + + /* Popup */ + [data-tooltip][data-inverted]:after { + background: @tooltipInvertedBackground; + color: @tooltipInvertedColor; + border: @tooltipInvertedBorder; + box-shadow: @tooltipInvertedBoxShadow; + } + [data-tooltip][data-inverted]:after .header { + background: @tooltipInvertedHeaderBackground; + color: @tooltipInvertedHeaderColor; + } + } + + & when (@variationPopupPosition) { + /*-------------- + Position + ---------------*/ + & when (@variationPopupTop) { + [data-position~="top"][data-tooltip]:before { + background: @arrowBottomBackground; + } + & when (@variationPopupCenter) { + /* Top Center */ + [data-position="top center"][data-tooltip]:after { + top: auto; + right: auto; + left: 50%; + bottom: 100%; + transform: translateX(-50%); + margin-bottom: @tooltipDistanceAway; + } + [data-position="top center"][data-tooltip]:before { + top: auto; + right: auto; + bottom: 100%; + left: 50%; + background: @tooltipArrowTopBackground; + margin-left: @tooltipArrowHorizontalOffset; + margin-bottom: -@tooltipArrowVerticalOffset; + } + } + & when (@variationPopupLeft) { + /* Top Left */ + [data-position="top left"][data-tooltip]:after { + top: auto; + right: auto; + left: 0; + bottom: 100%; + margin-bottom: @tooltipDistanceAway; + } + [data-position="top left"][data-tooltip]:before { + top: auto; + right: auto; + bottom: 100%; + left: @arrowDistanceFromEdge; + margin-left: @tooltipArrowHorizontalOffset; + margin-bottom: -@tooltipArrowVerticalOffset; + } + } + & when (@variationPopupRight) { + /* Top Right */ + [data-position="top right"][data-tooltip]:after { + top: auto; + left: auto; + right: 0; + bottom: 100%; + margin-bottom: @tooltipDistanceAway; + } + [data-position="top right"][data-tooltip]:before { + top: auto; + left: auto; + bottom: 100%; + right: @arrowDistanceFromEdge; + margin-left: @tooltipArrowHorizontalOffset; + margin-bottom: -@tooltipArrowVerticalOffset; + } + } + } + + & when (@variationPopupBottom) { + [data-position~="bottom"][data-tooltip]:before { + background: @arrowTopBackground; + box-shadow: @bottomArrowBoxShadow; + } + & when (@variationPopupCenter) { + /* Bottom Center */ + [data-position="bottom center"][data-tooltip]:after { + bottom: auto; + right: auto; + left: 50%; + top: 100%; + transform: translateX(-50%); + margin-top: @tooltipDistanceAway; + } + [data-position="bottom center"][data-tooltip]:before { + bottom: auto; + right: auto; + top: 100%; + left: 50%; + margin-left: @tooltipArrowHorizontalOffset; + margin-top: -@tooltipArrowVerticalOffset; + } + } + & when (@variationPopupLeft) { + /* Bottom Left */ + [data-position="bottom left"][data-tooltip]:after { + left: 0; + top: 100%; + margin-top: @tooltipDistanceAway; + } + [data-position="bottom left"][data-tooltip]:before { + bottom: auto; + right: auto; + top: 100%; + left: @arrowDistanceFromEdge; + margin-left: @tooltipArrowHorizontalOffset; + margin-top: -@tooltipArrowVerticalOffset; + } + } + & when (@variationPopupRight) { + /* Bottom Right */ + [data-position="bottom right"][data-tooltip]:after { + right: 0; + top: 100%; + margin-top: @tooltipDistanceAway; + } + [data-position="bottom right"][data-tooltip]:before { + bottom: auto; + left: auto; + top: 100%; + right: @arrowDistanceFromEdge; + margin-left: @tooltipArrowVerticalOffset; + margin-top: -@tooltipArrowHorizontalOffset; + } + } + } + & when (@variationPopupCenter) { + & when (@variationPopupLeft) { + /* Left Center */ + [data-position="left center"][data-tooltip]:after { + right: 100%; + top: 50%; + margin-right: @tooltipDistanceAway; + transform: translateY(-50%); + } + [data-position="left center"][data-tooltip]:before { + right: 100%; + top: 50%; + margin-top: @tooltipArrowVerticalOffset; + margin-right: @tooltipArrowHorizontalOffset; + background: @arrowCenterBackground; + box-shadow: @leftArrowBoxShadow; + } + } + & when (@variationPopupRight) { + /* Right Center */ + [data-position="right center"][data-tooltip]:after { + left: 100%; + top: 50%; + margin-left: @tooltipDistanceAway; + transform: translateY(-50%); + } + [data-position="right center"][data-tooltip]:before { + left: 100%; + top: 50%; + margin-top: @tooltipArrowHorizontalOffset; + margin-left: -@tooltipArrowVerticalOffset; + background: @arrowCenterBackground; + box-shadow: @rightArrowBoxShadow; + } + } + } + + & when (@variationPopupInverted) { + /* Inverted Arrow Color */ + & when (@variationPopupBottom) { + [data-inverted][data-position~="bottom"][data-tooltip]:before { + background: @invertedArrowTopBackground; + box-shadow: @bottomArrowBoxShadow; + } + } + & when (@variationPopupCenter) { + & when (@variationPopupLeft) { + [data-inverted][data-position="left center"][data-tooltip]:before { + background: @invertedArrowCenterBackground; + box-shadow: @leftArrowBoxShadow; + } + } + & when (@variationPopupRight) { + [data-inverted][data-position="right center"][data-tooltip]:before { + background: @invertedArrowCenterBackground; + box-shadow: @rightArrowBoxShadow; + } + } + } + & when (@variationPopupTop) { + [data-inverted][data-position~="top"][data-tooltip]:before { + background: @invertedArrowBottomBackground; + } + } + } + + & when (@variationPopupBottom) { + [data-position~="bottom"][data-tooltip]:before { + transform-origin: center bottom; + } + [data-position~="bottom"][data-tooltip]:after { + transform-origin: center top; + } + } + & when (@variationPopupCenter) { + & when (@variationPopupLeft) { + [data-position="left center"][data-tooltip]:before { + transform-origin: top center; + } + [data-position="left center"][data-tooltip]:after { + transform-origin: right center; + } + } + & when (@variationPopupRight) { + [data-position="right center"][data-tooltip]:before { + transform-origin: right center; + } + [data-position="right center"][data-tooltip]:after { + transform-origin: left center; + } + } + } + } + + & when (@variationPopupBasic) { + /*-------------- + Basic + ---------------*/ + [data-tooltip][data-variation~="basic"]:before { + display: none; + } + } +} + +/*-------------- + Spacing +---------------*/ + +.ui.popup { + margin: 0; +} + +& when (@variationPopupTop) { + /* Extending from Top */ + .ui.top.popup { + margin: 0 0 @popupDistanceAway; + } + & when (@variationPopupLeft) { + .ui.top.left.popup { + transform-origin: left bottom; + } + } + & when (@variationPopupCenter) { + .ui.top.center.popup { + transform-origin: center bottom; + } + } + & when (@variationPopupRight) { + .ui.top.right.popup { + transform-origin: right bottom; + } + } +} + +& when (@variationPopupCenter) { + /* Extending from Vertical Center */ + & when (@variationPopupLeft) { + .ui.left.center.popup { + margin: 0 @popupDistanceAway 0 0; + transform-origin: right 50%; + } + } + & when (@variationPopupRight) { + .ui.right.center.popup { + margin: 0 0 0 @popupDistanceAway; + transform-origin: left 50%; + } + } +} + +& when (@variationPopupBottom) { + /* Extending from Bottom */ + .ui.bottom.popup { + margin: @popupDistanceAway 0 0; + } + & when (@variationPopupLeft) { + .ui.bottom.left.popup { + transform-origin: left top; + } + } + & when (@variationPopupCenter) { + .ui.bottom.center.popup { + transform-origin: center top; + } + } + & when (@variationPopupRight) { + .ui.bottom.right.popup { + transform-origin: right top; + } + } + + /*-------------- + Pointer + ---------------*/ + + /*--- Below ---*/ + .ui.bottom.center.popup:before { + margin-left: @arrowOffset; + top: @arrowOffset; + left: 50%; + right: auto; + bottom: auto; + box-shadow: @bottomArrowBoxShadow; + } + + .ui.bottom.left.popup { + margin-left: @boxArrowOffset; + } + /*rtl:rename*/ + .ui.bottom.left.popup:before { + top: @arrowOffset; + left: @arrowDistanceFromEdge; + right: auto; + bottom: auto; + margin-left: 0; + box-shadow: @bottomArrowBoxShadow; + } + + .ui.bottom.right.popup { + margin-right: @boxArrowOffset; + } + /*rtl:rename*/ + .ui.bottom.right.popup:before { + top: @arrowOffset; + right: @arrowDistanceFromEdge; + bottom: auto; + left: auto; + margin-left: 0; + box-shadow: @bottomArrowBoxShadow; + } +} + +& when (@variationPopupTop) { + /*--- Above ---*/ + & when (@variationPopupCenter) { + .ui.top.center.popup:before { + top: auto; + right: auto; + bottom: @arrowOffset; + left: 50%; + margin-left: @arrowOffset; + } + } + & when (@variationPopupLeft) { + .ui.top.left.popup { + margin-left: @boxArrowOffset; + } + /*rtl:rename*/ + .ui.top.left.popup:before { + bottom: @arrowOffset; + left: @arrowDistanceFromEdge; + top: auto; + right: auto; + margin-left: 0; + } + } + & when (@variationPopupRight) { + .ui.top.right.popup { + margin-right: @boxArrowOffset; + } + /*rtl:rename*/ + .ui.top.right.popup:before { + bottom: @arrowOffset; + right: @arrowDistanceFromEdge; + top: auto; + left: auto; + margin-left: 0; + } + } +} + +& when (@variationPopupCenter) { + /*--- Left Center ---*/ + /*rtl:rename*/ + & when (@variationPopupLeft) { + .ui.left.center.popup:before { + top: 50%; + right: @arrowOffset; + bottom: auto; + left: auto; + margin-top: @arrowOffset; + box-shadow: @leftArrowBoxShadow; + } + } + & when (@variationPopupRight) { + /*--- Right Center ---*/ + /*rtl:rename*/ + .ui.right.center.popup:before { + top: 50%; + left: @arrowOffset; + bottom: auto; + right: auto; + margin-top: @arrowOffset; + box-shadow: @rightArrowBoxShadow; + } + } + & when (@variationPopupLeft) or (@variationPopupRight) { + .ui.right.center.popup:before, + .ui.left.center.popup:before { + background: @arrowCenterBackground; + } + } +} + +& when (@variationPopupBottom) { + /* Arrow Color By Location */ + .ui.bottom.popup:before { + background: @arrowTopBackground; + } +} + +& when (@variationPopupTop) { + .ui.top.popup:before { + background: @arrowBottomBackground; + } +} + +& when (@variationPopupInverted) { + & when (@variationPopupBottom) { + /* Inverted Arrow Color */ + .ui.inverted.bottom.popup:before { + background: @invertedArrowTopBackground; + } + } + & when (@variationPopupCenter) { + .ui.inverted.right.center.popup:before, + .ui.inverted.left.center.popup:before { + background: @invertedArrowCenterBackground; + } + } + & when (@variationPopupTop) { + .ui.inverted.top.popup:before { + background: @invertedArrowBottomBackground; + } + } +} + + +/******************************* + Coupling +*******************************/ + +/* Immediate Nested Grid */ +.ui.popup > .ui.grid:not(.padded) { + width: @nestedGridWidth; + margin: @nestedGridMargin; +} + +/******************************* + States +*******************************/ +& when (@variationPopupLoading) { + .ui.loading.popup { + display: block; + visibility: hidden; + z-index: @loadingZIndex; + } +} + +.ui.animating.popup, +.ui.visible.popup { + display: block; +} + +.ui.visible.popup { + transform: translateZ(0); + backface-visibility: hidden; +} + + +/******************************* + Variations +*******************************/ + +& when (@variationPopupBasic) { + /*-------------- + Basic + ---------------*/ + + .ui.basic.popup:before { + display: none; + } +} + +& when (@variationPopupFixed) { + .ui.fixed.popup { + width: @maxWidth; + } +} + +& when (@variationPopupWide) { + /*-------------- + Wide + ---------------*/ + + .ui.wide.popup { + max-width: @wideWidth; + &.fixed when (@variationPopupFixed) { + width: @wideWidth; + } + } + .ui[class*="very wide"].popup { + max-width: @veryWideWidth; + &.fixed when (@variationPopupFixed) { + width: @veryWideWidth; + } + } + + @media only screen and (max-width: @largestMobileScreen) { + .ui.wide.popup, + .ui[class*="very wide"].popup { + max-width: @maxWidth; + &.fixed when (@variationPopupFixed) { + width:@maxWidth; + } + } + } +} + +& when (@variationPopupFluid) { + /*-------------- + Fluid + ---------------*/ + + .ui.fluid.popup { + width: 100%; + max-width: none; + } +} + +& when (@variationPopupInverted) { + /*-------------- + Colors + ---------------*/ + + /* Inverted colors */ + .ui.inverted.popup { + background: @invertedBackground; + color: @invertedColor; + border: @invertedBorder; + box-shadow: @invertedBoxShadow; + } + .ui.inverted.popup .header { + background-color: @invertedHeaderBackground; + color: @invertedHeaderColor; + } + .ui.inverted.popup:before { + background-color: @invertedArrowColor; + box-shadow: none !important; + } +} + +& when (@variationPopupFlowing) { + /*-------------- + Flowing + ---------------*/ + + .ui.flowing.popup { + max-width: none; + } +} + + +/*-------------- + Sizes +---------------*/ + +.ui.popup { + font-size: @medium; +} +& when not (@variationPopupSizes = false) { + each(@variationPopupSizes, { + @s: @@value; + .ui.@{value}.popup { + font-size: @s; + } + & when (@variationPopupTooltip) { + [data-tooltip][data-variation~="@{value}"]:before, + [data-tooltip][data-variation~="@{value}"]:after { + font-size: @s; + } + } + }) +} + + +.loadUIOverrides(); diff --git a/semantic/src/definitions/modules/progress.js b/semantic/src/definitions/modules/progress.js new file mode 100644 index 0000000..0d90a4d --- /dev/null +++ b/semantic/src/definitions/modules/progress.js @@ -0,0 +1,1035 @@ +/*! + * # Fomantic-UI - Progress + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +'use strict'; + +$.isFunction = $.isFunction || function(obj) { + return typeof obj === "function" && typeof obj.nodeType !== "number"; +}; + +window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.fn.progress = 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), + + returnedValue + ; + + $allModules + .each(function() { + var + settings = ( $.isPlainObject(parameters) ) + ? $.extend(true, {}, $.fn.progress.settings, parameters) + : $.extend({}, $.fn.progress.settings), + + className = settings.className, + metadata = settings.metadata, + namespace = settings.namespace, + selector = settings.selector, + error = settings.error, + + eventNamespace = '.' + namespace, + moduleNamespace = 'module-' + namespace, + + $module = $(this), + $bars = $(this).find(selector.bar), + $progresses = $(this).find(selector.progress), + $label = $(this).find(selector.label), + + element = this, + instance = $module.data(moduleNamespace), + + animating = false, + transitionEnd, + module + ; + module = { + helper: { + sum: function (nums) { + return Array.isArray(nums) ? nums.reduce(function (left, right) { + return left + Number(right); + }, 0) : 0; + }, + /** + * Derive precision for multiple progress with total and values. + * + * This helper dervices a precision that is sufficiently large to show minimum value of multiple progress. + * + * Example1 + * - total: 1122 + * - values: [325, 111, 74, 612] + * - min ratio: 74/1122 = 0.0659... + * - required precision: 100 + * + * Example2 + * - total: 10541 + * - values: [3235, 1111, 74, 6121] + * - min ratio: 74/10541 = 0.0070... + * - required precision: 1000 + * + * @param min A minimum value within multiple values + * @param total A total amount of multiple values + * @returns {number} A precison. Could be 1, 10, 100, ... 1e+10. + */ + derivePrecision: function(min, total) { + var precisionPower = 0 + var precision = 1; + var ratio = min / total; + while (precisionPower < 10) { + ratio = ratio * precision; + if (ratio > 1) { + break; + } + precision = Math.pow(10, precisionPower++); + } + return precision; + }, + forceArray: function (element) { + return Array.isArray(element) + ? element + : !isNaN(element) + ? [element] + : typeof element == 'string' + ? element.split(',') + : [] + ; + } + }, + + initialize: function() { + module.set.duration(); + module.set.transitionEvent(); + module.debug(element); + + module.read.metadata(); + module.read.settings(); + + module.instantiate(); + }, + + instantiate: function() { + module.verbose('Storing instance of progress', module); + instance = module; + $module + .data(moduleNamespace, module) + ; + }, + destroy: function() { + module.verbose('Destroying previous progress for', $module); + clearInterval(instance.interval); + module.remove.state(); + $module.removeData(moduleNamespace); + instance = undefined; + }, + + reset: function() { + module.remove.nextValue(); + module.update.progress(0); + }, + + complete: function(keepState) { + if(module.percent === undefined || module.percent < 100) { + module.remove.progressPoll(); + if(keepState !== true){ + module.set.percent(100); + } + } + }, + + read: { + metadata: function() { + var + data = { + percent : module.helper.forceArray($module.data(metadata.percent)), + total : $module.data(metadata.total), + value : module.helper.forceArray($module.data(metadata.value)) + } + ; + if(data.total !== undefined) { + module.debug('Total value set from metadata', data.total); + module.set.total(data.total); + } + if(data.value.length > 0) { + module.debug('Current value set from metadata', data.value); + module.set.value(data.value); + module.set.progress(data.value); + } + if(data.percent.length > 0) { + module.debug('Current percent value set from metadata', data.percent); + module.set.percent(data.percent); + } + }, + settings: function() { + if(settings.total !== false) { + module.debug('Current total set in settings', settings.total); + module.set.total(settings.total); + } + if(settings.value !== false) { + module.debug('Current value set in settings', settings.value); + module.set.value(settings.value); + module.set.progress(module.value); + } + if(settings.percent !== false) { + module.debug('Current percent set in settings', settings.percent); + module.set.percent(settings.percent); + } + } + }, + + bind: { + transitionEnd: function(callback) { + var + transitionEnd = module.get.transitionEnd() + ; + $bars + .one(transitionEnd + eventNamespace, function(event) { + clearTimeout(module.failSafeTimer); + callback.call(this, event); + }) + ; + module.failSafeTimer = setTimeout(function() { + $bars.triggerHandler(transitionEnd); + }, settings.duration + settings.failSafeDelay); + module.verbose('Adding fail safe timer', module.timer); + } + }, + + increment: function(incrementValue) { + var + startValue, + newValue + ; + if( module.has.total() ) { + startValue = module.get.value(); + incrementValue = incrementValue || 1; + } + else { + startValue = module.get.percent(); + incrementValue = incrementValue || module.get.randomValue(); + } + newValue = startValue + incrementValue; + module.debug('Incrementing percentage by', startValue, newValue, incrementValue); + newValue = module.get.normalizedValue(newValue); + module.set.progress(newValue); + }, + decrement: function(decrementValue) { + var + total = module.get.total(), + startValue, + newValue + ; + if(total) { + startValue = module.get.value(); + decrementValue = decrementValue || 1; + newValue = startValue - decrementValue; + module.debug('Decrementing value by', decrementValue, startValue); + } + else { + startValue = module.get.percent(); + decrementValue = decrementValue || module.get.randomValue(); + newValue = startValue - decrementValue; + module.debug('Decrementing percentage by', decrementValue, startValue); + } + newValue = module.get.normalizedValue(newValue); + module.set.progress(newValue); + }, + + has: { + progressPoll: function() { + return module.progressPoll; + }, + total: function() { + return (module.get.total() !== false); + } + }, + + get: { + text: function(templateText, index) { + var + index_ = index || 0, + value = module.get.value(index_), + total = module.get.total(), + percent = (animating) + ? module.get.displayPercent(index_) + : module.get.percent(index_), + left = (total !== false) + ? Math.max(0,total - value) + : (100 - percent) + ; + templateText = templateText || ''; + templateText = templateText + .replace('{value}', value) + .replace('{total}', total || 0) + .replace('{left}', left) + .replace('{percent}', percent) + .replace('{bar}', settings.text.bars[index_] || '') + ; + module.verbose('Adding variables to progress bar text', templateText); + return templateText; + }, + + normalizedValue: function(value) { + if(value < 0) { + module.debug('Value cannot decrement below 0'); + return 0; + } + if(module.has.total()) { + if(value > module.total) { + module.debug('Value cannot increment above total', module.total); + return module.total; + } + } + else if(value > 100 ) { + module.debug('Value cannot increment above 100 percent'); + return 100; + } + return value; + }, + + updateInterval: function() { + if(settings.updateInterval == 'auto') { + return settings.duration; + } + return settings.updateInterval; + }, + + randomValue: function() { + module.debug('Generating random increment percentage'); + return Math.floor((Math.random() * settings.random.max) + settings.random.min); + }, + + numericValue: function(value) { + return (typeof value === 'string') + ? (value.replace(/[^\d.]/g, '') !== '') + ? +(value.replace(/[^\d.]/g, '')) + : false + : value + ; + }, + + transitionEnd: function() { + var + element = document.createElement('element'), + transitions = { + 'transition' :'transitionend', + 'OTransition' :'oTransitionEnd', + 'MozTransition' :'transitionend', + 'WebkitTransition' :'webkitTransitionEnd' + }, + transition + ; + for(transition in transitions){ + if( element.style[transition] !== undefined ){ + return transitions[transition]; + } + } + }, + + // gets current displayed percentage (if animating values this is the intermediary value) + displayPercent: function(index) { + var + $bar = $($bars[index]), + barWidth = $bar.width(), + totalWidth = $module.width(), + minDisplay = parseInt($bar.css('min-width'), 10), + displayPercent = (barWidth > minDisplay) + ? (barWidth / totalWidth * 100) + : module.percent + ; + return (settings.precision > 0) + ? Math.round(displayPercent * (10 * settings.precision)) / (10 * settings.precision) + : Math.round(displayPercent) + ; + }, + + percent: function(index) { + return module.percent && module.percent[index || 0] || 0; + }, + value: function(index) { + return module.nextValue || module.value && module.value[index || 0] || 0; + }, + total: function() { + return module.total !== undefined ? module.total : false; + } + }, + + create: { + progressPoll: function() { + module.progressPoll = setTimeout(function() { + module.update.toNextValue(); + module.remove.progressPoll(); + }, module.get.updateInterval()); + }, + }, + + is: { + complete: function() { + return module.is.success() || module.is.warning() || module.is.error(); + }, + success: function() { + return $module.hasClass(className.success); + }, + warning: function() { + return $module.hasClass(className.warning); + }, + error: function() { + return $module.hasClass(className.error); + }, + active: function() { + return $module.hasClass(className.active); + }, + visible: function() { + return $module.is(':visible'); + } + }, + + remove: { + progressPoll: function() { + module.verbose('Removing progress poll timer'); + if(module.progressPoll) { + clearTimeout(module.progressPoll); + delete module.progressPoll; + } + }, + nextValue: function() { + module.verbose('Removing progress value stored for next update'); + delete module.nextValue; + }, + state: function() { + module.verbose('Removing stored state'); + delete module.total; + delete module.percent; + delete module.value; + }, + active: function() { + module.verbose('Removing active state'); + $module.removeClass(className.active); + }, + success: function() { + module.verbose('Removing success state'); + $module.removeClass(className.success); + }, + warning: function() { + module.verbose('Removing warning state'); + $module.removeClass(className.warning); + }, + error: function() { + module.verbose('Removing error state'); + $module.removeClass(className.error); + } + }, + + set: { + barWidth: function(values) { + module.debug("set bar width with ", values); + values = module.helper.forceArray(values); + var firstNonZeroIndex = -1; + var lastNonZeroIndex = -1; + var valuesSum = module.helper.sum(values); + var barCounts = $bars.length; + var isMultiple = barCounts > 1; + var percents = values.map(function(value, index) { + var allZero = (index === barCounts - 1 && valuesSum === 0); + var $bar = $($bars[index]); + if (value === 0 && isMultiple && !allZero) { + $bar.css('display', 'none'); + } else { + if (isMultiple && allZero) { + $bar.css('background', 'transparent'); + } + if (firstNonZeroIndex == -1) { + firstNonZeroIndex = index; + } + lastNonZeroIndex = index; + $bar.css({ + display: 'block', + width: value + '%' + }); + } + return parseFloat(value); + }); + values.forEach(function(_, index) { + var $bar = $($bars[index]); + $bar.css({ + borderTopLeftRadius: index == firstNonZeroIndex ? '' : 0, + borderBottomLeftRadius: index == firstNonZeroIndex ? '' : 0, + borderTopRightRadius: index == lastNonZeroIndex ? '' : 0, + borderBottomRightRadius: index == lastNonZeroIndex ? '' : 0 + }); + }); + $module + .attr('data-percent', percents) + ; + }, + duration: function(duration) { + duration = duration || settings.duration; + duration = (typeof duration == 'number') + ? duration + 'ms' + : duration + ; + module.verbose('Setting progress bar transition duration', duration); + $bars + .css({ + 'transition-duration': duration + }) + ; + }, + percent: function(percents) { + percents = module.helper.forceArray(percents).map(function(percent) { + return (typeof percent == 'string') + ? +(percent.replace('%', '')) + : percent + ; + }); + var hasTotal = module.has.total(); + var totalPercent = module.helper.sum(percents); + var isMultipleValues = percents.length > 1 && hasTotal; + var sumTotal = module.helper.sum(module.helper.forceArray(module.value)); + if (isMultipleValues && sumTotal > module.total) { + // Sum values instead of pecents to avoid precision issues when summing floats + module.error(error.sumExceedsTotal, sumTotal, module.total); + } else if (!isMultipleValues && totalPercent > 100) { + // Sum before rounding since sum of rounded may have error though sum of actual is fine + module.error(error.tooHigh, totalPercent); + } else if (totalPercent < 0) { + module.error(error.tooLow, totalPercent); + } else { + var autoPrecision = settings.precision > 0 + ? settings.precision + : isMultipleValues + ? module.helper.derivePrecision(Math.min.apply(null, module.value), module.total) + : 0; + + // round display percentage + var roundedPercents = percents.map(function (percent) { + return (autoPrecision > 0) + ? Math.round(percent * (10 * autoPrecision)) / (10 * autoPrecision) + : Math.round(percent) + ; + }); + module.percent = roundedPercents; + if (hasTotal) { + module.value = roundedPercents.map(function (percent) { + return (autoPrecision > 0) + ? Math.round((percent / 100) * module.total * (10 * autoPrecision)) / (10 * autoPrecision) + : Math.round((percent / 100) * module.total * 10) / 10 + ; + }); + if (settings.limitValues) { + module.value = module.value.map(function (value) { + return Math.max(0, Math.min(100, value)); + }); + } + } + module.set.barWidth(percents); + module.set.labelInterval(); + module.set.labels(); + } + settings.onChange.call(element, percents, module.value, module.total); + }, + labelInterval: function() { + var + animationCallback = function() { + module.verbose('Bar finished animating, removing continuous label updates'); + clearInterval(module.interval); + animating = false; + module.set.labels(); + } + ; + clearInterval(module.interval); + module.bind.transitionEnd(animationCallback); + animating = true; + module.interval = setInterval(function() { + var + isInDOM = $.contains(document.documentElement, element) + ; + if(!isInDOM) { + clearInterval(module.interval); + animating = false; + } + module.set.labels(); + }, settings.framerate); + }, + labels: function() { + module.verbose('Setting both bar progress and outer label text'); + module.set.barLabel(); + module.set.state(); + }, + label: function(text) { + text = text || ''; + if(text) { + text = module.get.text(text); + module.verbose('Setting label to text', text); + $label.text(text); + } + }, + state: function(percent) { + percent = (percent !== undefined) + ? percent + : module.helper.sum(module.percent) + ; + if(percent === 100) { + if(settings.autoSuccess && $bars.length === 1 && !(module.is.warning() || module.is.error() || module.is.success())) { + module.set.success(); + module.debug('Automatically triggering success at 100%'); + } + else { + module.verbose('Reached 100% removing active state'); + module.remove.active(); + module.remove.progressPoll(); + } + } + else if(percent > 0) { + module.verbose('Adjusting active progress bar label', percent); + module.set.active(); + } + else { + module.remove.active(); + module.set.label(settings.text.active); + } + }, + barLabel: function(text) { + $progresses.map(function(index, element){ + var $progress = $(element); + if (text !== undefined) { + $progress.text( module.get.text(text, index) ); + } + else if (settings.label == 'ratio' && module.has.total()) { + module.verbose('Adding ratio to bar label'); + $progress.text( module.get.text(settings.text.ratio, index) ); + } + else if (settings.label == 'percent') { + module.verbose('Adding percentage to bar label'); + $progress.text( module.get.text(settings.text.percent, index) ); + } + }); + }, + active: function(text) { + text = text || settings.text.active; + module.debug('Setting active state'); + if(settings.showActivity && !module.is.active() ) { + $module.addClass(className.active); + } + module.remove.warning(); + module.remove.error(); + module.remove.success(); + text = settings.onLabelUpdate('active', text, module.value, module.total); + if(text) { + module.set.label(text); + } + module.bind.transitionEnd(function() { + settings.onActive.call(element, module.value, module.total); + }); + }, + success : function(text, keepState) { + text = text || settings.text.success || settings.text.active; + module.debug('Setting success state'); + $module.addClass(className.success); + module.remove.active(); + module.remove.warning(); + module.remove.error(); + module.complete(keepState); + if(settings.text.success) { + text = settings.onLabelUpdate('success', text, module.value, module.total); + module.set.label(text); + } + else { + text = settings.onLabelUpdate('active', text, module.value, module.total); + module.set.label(text); + } + module.bind.transitionEnd(function() { + settings.onSuccess.call(element, module.total); + }); + }, + warning : function(text, keepState) { + text = text || settings.text.warning; + module.debug('Setting warning state'); + $module.addClass(className.warning); + module.remove.active(); + module.remove.success(); + module.remove.error(); + module.complete(keepState); + text = settings.onLabelUpdate('warning', text, module.value, module.total); + if(text) { + module.set.label(text); + } + module.bind.transitionEnd(function() { + settings.onWarning.call(element, module.value, module.total); + }); + }, + error : function(text, keepState) { + text = text || settings.text.error; + module.debug('Setting error state'); + $module.addClass(className.error); + module.remove.active(); + module.remove.success(); + module.remove.warning(); + module.complete(keepState); + text = settings.onLabelUpdate('error', text, module.value, module.total); + if(text) { + module.set.label(text); + } + module.bind.transitionEnd(function() { + settings.onError.call(element, module.value, module.total); + }); + }, + transitionEvent: function() { + transitionEnd = module.get.transitionEnd(); + }, + total: function(totalValue) { + module.total = totalValue; + }, + value: function(value) { + module.value = module.helper.forceArray(value); + }, + progress: function(value) { + if(!module.has.progressPoll()) { + module.debug('First update in progress update interval, immediately updating', value); + module.update.progress(value); + module.create.progressPoll(); + } + else { + module.debug('Updated within interval, setting next update to use new value', value); + module.set.nextValue(value); + } + }, + nextValue: function(value) { + module.nextValue = value; + } + }, + + update: { + toNextValue: function() { + var + nextValue = module.nextValue + ; + if(nextValue) { + module.debug('Update interval complete using last updated value', nextValue); + module.update.progress(nextValue); + module.remove.nextValue(); + } + }, + progress: function(values) { + var hasTotal = module.has.total(); + if (hasTotal) { + module.set.value(values); + } + var percentCompletes = module.helper.forceArray(values).map(function(value) { + var + percentComplete + ; + value = module.get.numericValue(value); + if (value === false) { + module.error(error.nonNumeric, value); + } + value = module.get.normalizedValue(value); + if (hasTotal) { + percentComplete = module.total > 0 ? (value / module.total) * 100 : 100; + module.debug('Calculating percent complete from total', percentComplete); + } + else { + percentComplete = value; + module.debug('Setting value to exact percentage value', percentComplete); + } + return percentComplete; + }); + module.set.percent( percentCompletes ); + } + }, + + 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(Array.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.progress.settings = { + + name : 'Progress', + namespace : 'progress', + + silent : false, + debug : false, + verbose : false, + performance : true, + + random : { + min : 2, + max : 5 + }, + + duration : 300, + + updateInterval : 'auto', + + autoSuccess : true, + showActivity : true, + limitValues : true, + + label : 'percent', + precision : 0, + framerate : (1000 / 30), /// 30 fps + + percent : false, + total : false, + value : false, + + // delay in ms for fail safe animation callback + failSafeDelay : 100, + + onLabelUpdate : function(state, text, value, total){ + return text; + }, + onChange : function(percent, value, total){}, + onSuccess : function(total){}, + onActive : function(value, total){}, + onError : function(value, total){}, + onWarning : function(value, total){}, + + error : { + method : 'The method you called is not defined.', + nonNumeric : 'Progress value is non numeric', + tooHigh : 'Value specified is above 100%', + tooLow : 'Value specified is below 0%', + sumExceedsTotal : 'Sum of multple values exceed total', + }, + + regExp: { + variable: /\{\$*[A-z0-9]+\}/g + }, + + metadata: { + percent : 'percent', + total : 'total', + value : 'value' + }, + + selector : { + bar : '> .bar', + label : '> .label', + progress : '.bar > .progress' + }, + + text : { + active : false, + error : false, + success : false, + warning : false, + percent : '{percent}%', + ratio : '{value} of {total}', + bars : [''] + }, + + className : { + active : 'active', + error : 'error', + success : 'success', + warning : 'warning' + } + +}; + + +})( jQuery, window, document ); diff --git a/semantic/src/definitions/modules/progress.less b/semantic/src/definitions/modules/progress.less new file mode 100644 index 0000000..e5300d3 --- /dev/null +++ b/semantic/src/definitions/modules/progress.less @@ -0,0 +1,618 @@ +/*! + * # Fomantic-UI - Progress Bar + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + + +/******************************* + Theme +*******************************/ + +@type : 'module'; +@element : 'progress'; + +@import (multiple) '../../theme.config'; + +/******************************* + Progress +*******************************/ + +.ui.progress { + position: relative; + display: block; + max-width: 100%; + border: @border; + margin: @margin; + box-shadow: @boxShadow; + background: @background; + padding: @padding; + border-radius: @borderRadius; +} + +.ui.progress:first-child { + margin: @firstMargin; +} +.ui.progress:last-child { + margin: @lastMargin; +} + +/******************************* + Content +*******************************/ + +/* Activity Bar */ +.ui.progress .bar { + display: block; + line-height: 1; + position: @barPosition; + width: @barInitialWidth; + min-width: @barMinWidth; + background: @barBackground; + border-radius: @barBorderRadius; + transition: @barTransition; + overflow: hidden; +} +.ui.ui.ui.progress:not([data-percent]):not(.indeterminate) .bar, +.ui.ui.ui.progress[data-percent="0"]:not(.indeterminate) .bar { + background:transparent; +} +.ui.progress[data-percent="0"] .bar .progress { + color: @textColor; +} +& when (@variationProgressInverted) { + .ui.inverted.progress[data-percent="0"] .bar .progress { + color: @invertedTextColor; + } +} + +/* Percent Complete */ +.ui.progress .bar > .progress { + white-space: nowrap; + position: @progressPosition; + width: @progressWidth; + font-size: @progressSize; + top: @progressTop; + right: @progressRight; + left: @progressLeft; + bottom: @progressBottom; + color: @progressColor; + text-shadow: @progressTextShadow; + margin-top: @progressOffset; + font-weight: @progressFontWeight; + text-align: @progressTextAlign; +} + +/* Label */ +.ui.progress > .label { + position: absolute; + width: @labelWidth; + font-size: @labelSize; + top: @labelTop; + right: @labelRight; + left: @labelLeft; + bottom: @labelBottom; + color: @labelColor; + font-weight: @labelFontWeight; + text-shadow: @labelTextShadow; + margin-top: @labelOffset; + text-align: @labelTextAlign; + transition: @labelTransition; +} + + +/******************************* + Types +*******************************/ + +& when (@variationProgressIndicating) { + /* Indicating */ + .ui.indicating.progress[data-percent^="1"] .bar, + .ui.indicating.progress[data-percent^="2"] .bar { + background-color: @indicatingFirstColor; + } + .ui.indicating.progress[data-percent^="3"] .bar { + background-color: @indicatingSecondColor; + } + .ui.indicating.progress[data-percent^="4"] .bar, + .ui.indicating.progress[data-percent^="5"] .bar { + background-color: @indicatingThirdColor; + } + .ui.indicating.progress[data-percent^="6"] .bar { + background-color: @indicatingFourthColor; + } + .ui.indicating.progress[data-percent^="7"] .bar, + .ui.indicating.progress[data-percent^="8"] .bar { + background-color: @indicatingFifthColor; + } + .ui.indicating.progress[data-percent^="9"] .bar, + .ui.indicating.progress[data-percent^="100"] .bar { + background-color: @indicatingSixthColor; + } + + /* Indicating Label */ + .ui.indicating.progress[data-percent^="1"] .label, + .ui.indicating.progress[data-percent^="2"] .label { + color: @indicatingFirstLabelColor; + } + .ui.indicating.progress[data-percent^="3"] .label { + color: @indicatingSecondLabelColor; + } + .ui.indicating.progress[data-percent^="4"] .label, + .ui.indicating.progress[data-percent^="5"] .label { + color: @indicatingThirdLabelColor; + } + .ui.indicating.progress[data-percent^="6"] .label { + color: @indicatingFourthLabelColor; + } + .ui.indicating.progress[data-percent^="7"] .label, + .ui.indicating.progress[data-percent^="8"] .label { + color: @indicatingFifthLabelColor; + } + .ui.indicating.progress[data-percent^="9"] .label, + .ui.indicating.progress[data-percent^="100"] .label { + color: @indicatingSixthLabelColor; + } + + & when (@variationProgressInverted) { + /* Inverted Indicating Label */ + .ui.inverted.indicating.progress[data-percent^="1"] .label, + .ui.inverted.indicating.progress[data-percent^="2"] .label { + color: @invertedIndicatingFirstLabelColor; + } + .ui.inverted.indicating.progress[data-percent^="3"] .label { + color: @invertedIndicatingSecondLabelColor; + } + .ui.inverted.indicating.progress[data-percent^="4"] .label, + .ui.inverted.indicating.progress[data-percent^="5"] .label { + color: @invertedIndicatingThirdLabelColor; + } + .ui.inverted.indicating.progress[data-percent^="6"] .label { + color: @invertedIndicatingFourthLabelColor; + } + .ui.inverted.indicating.progress[data-percent^="7"] .label, + .ui.inverted.indicating.progress[data-percent^="8"] .label { + color: @invertedIndicatingFifthLabelColor; + } + .ui.inverted.indicating.progress[data-percent^="9"] .label, + .ui.inverted.indicating.progress[data-percent^="100"] .label { + color: @invertedIndicatingSixthLabelColor; + } + } + + /* Single Digits */ + .ui.indicating.progress[data-percent="1"] .bar, .ui.indicating.progress[data-percent^="1."] .bar, + .ui.indicating.progress[data-percent="2"] .bar, .ui.indicating.progress[data-percent^="2."] .bar, + .ui.indicating.progress[data-percent="3"] .bar, .ui.indicating.progress[data-percent^="3."] .bar, + .ui.indicating.progress[data-percent="4"] .bar, .ui.indicating.progress[data-percent^="4."] .bar, + .ui.indicating.progress[data-percent="5"] .bar, .ui.indicating.progress[data-percent^="5."] .bar, + .ui.indicating.progress[data-percent="6"] .bar, .ui.indicating.progress[data-percent^="6."] .bar, + .ui.indicating.progress[data-percent="7"] .bar, .ui.indicating.progress[data-percent^="7."] .bar, + .ui.indicating.progress[data-percent="8"] .bar, .ui.indicating.progress[data-percent^="8."] .bar, + .ui.indicating.progress[data-percent="9"] .bar, .ui.indicating.progress[data-percent^="9."] .bar { + background-color: @indicatingFirstColor; + } + .ui.indicating.progress[data-percent="0"] .label, .ui.indicating.progress[data-percent^="0."] .label, + .ui.indicating.progress[data-percent="1"] .label, .ui.indicating.progress[data-percent^="1."] .label, + .ui.indicating.progress[data-percent="2"] .label, .ui.indicating.progress[data-percent^="2."] .label, + .ui.indicating.progress[data-percent="3"] .label, .ui.indicating.progress[data-percent^="3."] .label, + .ui.indicating.progress[data-percent="4"] .label, .ui.indicating.progress[data-percent^="4."] .label, + .ui.indicating.progress[data-percent="5"] .label, .ui.indicating.progress[data-percent^="5."] .label, + .ui.indicating.progress[data-percent="6"] .label, .ui.indicating.progress[data-percent^="6."] .label, + .ui.indicating.progress[data-percent="7"] .label, .ui.indicating.progress[data-percent^="7."] .label, + .ui.indicating.progress[data-percent="8"] .label, .ui.indicating.progress[data-percent^="8."] .label, + .ui.indicating.progress[data-percent="9"] .label, .ui.indicating.progress[data-percent^="9."] .label { + color: @indicatingFirstLabelColor; + } + & when (@variationProgressInverted) { + .ui.inverted.indicating.progress[data-percent="0"] .label, .ui.inverted.indicating.progress[data-percent^="0."] .label, + .ui.inverted.indicating.progress[data-percent="1"] .label, .ui.inverted.indicating.progress[data-percent^="1."] .label, + .ui.inverted.indicating.progress[data-percent="2"] .label, .ui.inverted.indicating.progress[data-percent^="2."] .label, + .ui.inverted.indicating.progress[data-percent="3"] .label, .ui.inverted.indicating.progress[data-percent^="3."] .label, + .ui.inverted.indicating.progress[data-percent="4"] .label, .ui.inverted.indicating.progress[data-percent^="4."] .label, + .ui.inverted.indicating.progress[data-percent="5"] .label, .ui.inverted.indicating.progress[data-percent^="5."] .label, + .ui.inverted.indicating.progress[data-percent="6"] .label, .ui.inverted.indicating.progress[data-percent^="6."] .label, + .ui.inverted.indicating.progress[data-percent="7"] .label, .ui.inverted.indicating.progress[data-percent^="7."] .label, + .ui.inverted.indicating.progress[data-percent="8"] .label, .ui.inverted.indicating.progress[data-percent^="8."] .label, + .ui.inverted.indicating.progress[data-percent="9"] .label, .ui.inverted.indicating.progress[data-percent^="9."] .label { + color: @invertedIndicatingFirstLabelColor; + } + } + + /* Indicating Success */ + .ui.ui.indicating.progress.success .label { + color: @successHeaderColor; + } +} + +& when (@variationProgressMultiple) { + /* Multiple */ + .ui.multiple.progress { + display: flex; + } +} + +/******************************* + States +*******************************/ + +& when (@variationProgressSuccess) { + /*-------------- + Success + ---------------*/ + + .ui.ui.progress.success .bar { + background-color: @successColor; + } + .ui.ui.progress.success .bar, + .ui.ui.progress.success .bar::after { + animation: none; + } + .ui.progress.success > .label { + color: @successHeaderColor; + } +} + +& when (@variationProgressWarning) { + /*-------------- + Warning + ---------------*/ + + .ui.ui.progress.warning .bar { + background-color: @warningColor; + } + .ui.ui.progress.warning .bar, + .ui.ui.progress.warning .bar::after { + animation: none; + } + .ui.progress.warning > .label { + color: @warningHeaderColor; + } +} + +& when (@variationProgressError) { + /*-------------- + Error + ---------------*/ + + .ui.ui.progress.error .bar { + background-color: @errorColor; + } + .ui.ui.progress.error .bar, + .ui.ui.progress.error .bar::after { + animation: none; + } + .ui.progress.error > .label { + color: @errorHeaderColor; + } +} + +& when (@variationProgressActive) { + /*-------------- + Active + ---------------*/ + + .ui.active.progress .bar { + position: relative; + min-width: @activeMinWidth; + } + .ui.active.progress .bar::after { + content: ''; + opacity: 0; + + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: @activePulseColor; + + border-radius: @barBorderRadius; + + animation: progress-active @activePulseDuration @defaultEasing infinite; + transform-origin: left; + } + @keyframes progress-active { + 0% { + opacity: @activePulseMaxOpacity; + transform: scale(0, 1); + } + 100% { + opacity: 0; + transform: scale(1); + } + } +} + +& when (@variationProgressDisabled) { + /*-------------- + Disabled + ---------------*/ + + .ui.disabled.progress { + opacity: 0.35; + } + .ui.ui.disabled.progress .bar, + .ui.ui.disabled.progress .bar::after { + animation: none; + } +} + + +/******************************* + Variations +*******************************/ + +& when (@variationProgressInverted) { + /*-------------- + Inverted + ---------------*/ + + .ui.inverted.progress { + background: @invertedBackground; + border: @invertedBorder; + } + .ui.inverted.progress .bar { + background: @invertedBarBackground; + } + .ui.inverted.progress .bar > .progress { + color: @invertedProgressColor; + } + .ui.inverted.progress > .label { + color: @invertedLabelColor; + } + & when (@variationProgressSuccess) { + .ui.inverted.progress.success > .label { + color: @successColor; + } + } + & when (@variationProgressWarning) { + .ui.inverted.progress.warning > .label { + color: @warningColor; + } + } + & when (@variationProgressError) { + .ui.inverted.progress.error > .label { + color: @errorColor; + } + } +} + +& when (@variationProgressAttached) { + /*-------------- + Attached + ---------------*/ + + /* bottom attached */ + .ui.progress.attached { + background: @attachedBackground; + position: relative; + border: none; + margin: 0; + } + .ui.progress.attached, + .ui.progress.attached .bar { + display: block; + height: @attachedHeight; + padding: 0; + overflow: hidden; + border-radius: 0 0 @attachedBorderRadius @attachedBorderRadius; + } + .ui.progress.attached .bar { + border-radius: 0; + } + + /* top attached */ + .ui.progress.top.attached, + .ui.progress.top.attached .bar { + top: 0; + border-radius: @attachedBorderRadius @attachedBorderRadius 0 0; + } + .ui.progress.top.attached .bar { + border-radius: 0; + } + + /* Coupling */ + + .ui.segment > .ui.attached.progress, + .ui.card > .ui.attached.progress { + position: absolute; + top: auto; + left: 0; + bottom: 100%; + width: 100%; + } + + .ui.segment > .ui.bottom.attached.progress, + .ui.card > .ui.bottom.attached.progress { + top: 100%; + bottom: auto; + } +} + +/*-------------- + Colors +---------------*/ + +each(@colors, { + @color: replace(@key, '@', ''); + @c: @colors[@@color][color]; + @l: @colors[@@color][light]; + + .ui.indeterminate.@{color}.progress .bar::before, + .ui.@{color}.progress .bar, + .ui.progress .@{color}.bar { + background-color: @c; + } + & when (@variationProgressInverted) { + .ui.inverted.indeterminate.@{color}.progress .bar::before, + .ui.@{color}.inverted.progress .bar, + .ui.inverted.progress .@{color}.bar { + background-color: @l; + } + } +}) + +/*-------------- + Sizes +---------------*/ + +.ui.progress { + font-size: @medium; +} +.ui.progress .bar { + height: @barHeight; +} +& when not (@variationProgressSizes = false) { + each(@variationProgressSizes, { + @h: @{value}BarHeight; + @s: @@value; + .ui.@{value}.progress { + font-size: @s; + } + .ui.@{value}.progress .bar { + height: @@h; + } + }) +} + +& when (@variationProgressIndeterminate) { + /*--------------- + Indeterminate + ----------------*/ + + .ui.indeterminate.progress .bar { + width: 100%; + } + .ui.indeterminate.progress .bar .progress, + .ui.progress .bar .centered.progress { + text-align: center; + position: relative; + } + .ui.indeterminate.progress .bar::before { + content: ''; + position: absolute; + top: 0; + bottom: 0; + border-radius: @barBorderRadius; + animation: progress-pulsating @indeterminatePulseDuration @defaultEasing infinite; + transform-origin: center; + width: 100%; + } + & when (@variationProgressSpeeds) { + .ui.slow.indeterminate.progress .bar::before { + animation-duration: @indeterminatePulseDurationSlow; + } + .ui.fast.indeterminate.progress .bar::before { + animation-duration: @indeterminatePulseDurationFast; + } + } + & when (@variationProgressSwinging) { + .ui.swinging.indeterminate.progress .bar::before { + transform-origin: left; + animation-name: progress-swinging; + } + } + & when (@variationProgressSliding) { + .ui.sliding.indeterminate.progress .bar::before { + transform-origin: left; + animation-name: progress-sliding; + } + } + & when (@variationProgressFilling) { + .ui.filling.indeterminate.progress .bar::before { + animation-name: progress-filling; + } + } + .ui.indeterminate.progress:not(.sliding):not(.filling):not(.swinging) .bar::before { + background: @indeterminatePulseColor; + } + & when (@variationProgressSliding) or (@variationProgressSwinging) or (@variationProgressFilling) { + .ui.sliding.indeterminate.progress .bar, + .ui.swinging.indeterminate.progress .bar, + .ui.filling.indeterminate.progress .bar { + background: @background; + } + & when (@variationProgressSliding) or (@variationProgressSwinging) { + .ui.sliding.indeterminate.progress .bar .progress, + .ui.swinging.indeterminate.progress .bar .progress { + color: @invertedProgressColor; + } + } + & when (@variationProgressInverted) { + .ui.inverted.sliding.indeterminate.progress .bar, + .ui.inverted.swinging.indeterminate.progress .bar, + .ui.inverted.filling.indeterminate.progress .bar { + background: @invertedBackground; + } + & when (@variationProgressSliding) or (@variationProgressSwinging) { + .ui.inverted.sliding.indeterminate.progress .bar .progress, + .ui.inverted.swinging.indeterminate.progress .bar .progress { + color: @progressColor; + } + } + } + & when (@variationProgressSwinging) { + @keyframes progress-swinging { + 0%, 100% { + width:10%; + left:-25%; + } + 25%, 65% { + width:70%; + } + 50% { + width: 10%; + left:100%; + } + } + } + + & when (@variationProgressSliding) { + @keyframes progress-sliding { + 0% { + width:10%; + left:-25%; + } + 50% { + width:70%; + } + 100% { + width:10%; + left:100%; + } + } + } + + & when (@variationProgressFilling) { + @keyframes progress-filling { + 0% { + transform: scale(0,1); + } + 80% { + transform: scale(1); + opacity:1; + } + 100% { + opacity:0; + } + } + } + } + @keyframes progress-pulsating { + 0% { + transform: scale(0,1); + opacity:0.7; + } + 100% { + transform: scale(1); + opacity:0; + } + } +} + +.loadUIOverrides(); diff --git a/semantic/src/definitions/modules/rating.js b/semantic/src/definitions/modules/rating.js new file mode 100644 index 0000000..8a81011 --- /dev/null +++ b/semantic/src/definitions/modules/rating.js @@ -0,0 +1,554 @@ +/*! + * # Fomantic-UI - Rating + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +'use strict'; + +$.isFunction = $.isFunction || function(obj) { + return typeof obj === "function" && typeof obj.nodeType !== "number"; +}; + +window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.fn.rating = 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), + returnedValue + ; + $allModules + .each(function() { + var + settings = ( $.isPlainObject(parameters) ) + ? $.extend(true, {}, $.fn.rating.settings, parameters) + : $.extend({}, $.fn.rating.settings), + + namespace = settings.namespace, + className = settings.className, + metadata = settings.metadata, + selector = settings.selector, + cssVars = settings.cssVars, + + eventNamespace = '.' + namespace, + moduleNamespace = 'module-' + namespace, + + element = this, + instance = $(this).data(moduleNamespace), + + $module = $(this), + $icon = $module.find(selector.icon), + + initialLoad, + module + ; + + module = { + + initialize: function() { + module.verbose('Initializing rating module', settings); + + if($icon.length === 0) { + module.setup.layout(); + } + + if(settings.interactive && !module.is.disabled()) { + module.enable(); + } + else { + module.disable(); + } + module.set.initialLoad(); + module.set.rating( module.get.initialRating() ); + module.remove.initialLoad(); + module.instantiate(); + }, + + instantiate: function() { + module.verbose('Instantiating module', settings); + instance = module; + $module + .data(moduleNamespace, module) + ; + }, + + destroy: function() { + module.verbose('Destroying previous instance', instance); + module.remove.events(); + $module + .removeData(moduleNamespace) + ; + }, + + refresh: function() { + $icon = $module.find(selector.icon); + }, + + setup: { + layout: function() { + var + maxRating = module.get.maxRating(), + icon = module.get.icon(), + html = $.fn.rating.settings.templates.icon(maxRating, icon) + ; + module.debug('Generating icon html dynamically'); + $module + .html(html) + ; + module.refresh(); + } + }, + + event: { + mouseenter: function() { + var + $activeIcon = $(this) + ; + $activeIcon + .nextAll() + .removeClass(className.selected) + ; + $module + .addClass(className.selected) + ; + $activeIcon + .addClass(className.selected) + .prevAll() + .addClass(className.selected) + ; + }, + mouseleave: function() { + $module + .removeClass(className.selected) + ; + $icon + .removeClass(className.selected) + ; + }, + click: function() { + var + $activeIcon = $(this), + currentRating = module.get.rating(), + rating = $icon.index($activeIcon) + 1, + canClear = (settings.clearable == 'auto') + ? ($icon.length === 1) + : settings.clearable + ; + if(canClear && currentRating == rating) { + module.clearRating(); + } + else { + module.set.rating( rating ); + } + } + }, + + clearRating: function() { + module.debug('Clearing current rating'); + module.set.rating(0); + }, + + bind: { + events: function() { + module.verbose('Binding events'); + $module + .on('mouseenter' + eventNamespace, selector.icon, module.event.mouseenter) + .on('mouseleave' + eventNamespace, selector.icon, module.event.mouseleave) + .on('click' + eventNamespace, selector.icon, module.event.click) + ; + } + }, + + remove: { + events: function() { + module.verbose('Removing events'); + $module + .off(eventNamespace) + ; + }, + initialLoad: function() { + initialLoad = false; + } + }, + + enable: function() { + module.debug('Setting rating to interactive mode'); + module.bind.events(); + $module + .removeClass(className.disabled) + ; + }, + + disable: function() { + module.debug('Setting rating to read-only mode'); + module.remove.events(); + $module + .addClass(className.disabled) + ; + }, + + is: { + initialLoad: function() { + return initialLoad; + }, + disabled: function() { + return $module.hasClass(className.disabled); + } + }, + + get: { + icon: function(){ + var icon = $module.data(metadata.icon); + if (icon) { + $module.removeData(metadata.icon); + } + return icon || settings.icon; + }, + initialRating: function() { + if($module.data(metadata.rating) !== undefined) { + $module.removeData(metadata.rating); + return $module.data(metadata.rating); + } + return settings.initialRating; + }, + maxRating: function() { + if($module.data(metadata.maxRating) !== undefined) { + $module.removeData(metadata.maxRating); + return $module.data(metadata.maxRating); + } + return settings.maxRating; + }, + rating: function() { + var + currentRating = $icon.filter('.' + className.active).length + ; + module.verbose('Current rating retrieved', currentRating); + return currentRating; + } + }, + + set: { + rating: function(rating) { + var + ratingIndex = Math.floor( + (rating - 1 >= 0) + ? (rating - 1) + : 0 + ), + $activeIcon = $icon.eq(ratingIndex), + $partialActiveIcon = rating <= 1 + ? $activeIcon + : $activeIcon.next() + , + filledPercentage = (rating % 1) * 100 + ; + $module + .removeClass(className.selected) + ; + $icon + .removeClass(className.selected) + .removeClass(className.active) + .removeClass(className.partiallyActive) + ; + if(rating > 0) { + module.verbose('Setting current rating to', rating); + $activeIcon + .prevAll() + .addBack() + .addClass(className.active) + ; + if($activeIcon.next() && rating % 1 !== 0) { + $partialActiveIcon + .addClass(className.partiallyActive) + .addClass(className.active) + ; + $partialActiveIcon + .css(cssVars.filledCustomPropName, filledPercentage + '%') + ; + if($partialActiveIcon.css('backgroundColor') === 'transparent') { + $partialActiveIcon + .removeClass(className.partiallyActive) + .removeClass(className.active) + ; + } + } + } + if(!module.is.initialLoad()) { + settings.onRate.call(element, rating); + } + }, + initialLoad: function() { + initialLoad = true; + } + }, + + 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($allModules.length > 1) { + title += ' ' + '(' + $allModules.length + ')'; + } + 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 { + return false; + } + }); + } + if ( $.isFunction( found ) ) { + response = found.apply(context, passedArguments); + } + else if(found !== undefined) { + response = found; + } + if(Array.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.rating.settings = { + + name : 'Rating', + namespace : 'rating', + + icon : 'star', + + silent : false, + debug : false, + verbose : false, + performance : true, + + initialRating : 0, + interactive : true, + maxRating : 4, + clearable : 'auto', + + fireOnInit : false, + + onRate : function(rating){}, + + error : { + method : 'The method you called is not defined', + noMaximum : 'No maximum rating specified. Cannot generate HTML automatically' + }, + + + metadata: { + rating : 'rating', + maxRating : 'maxRating', + icon : 'icon' + }, + + className : { + active : 'active', + disabled : 'disabled', + selected : 'selected', + loading : 'loading', + partiallyActive : 'partial' + }, + + cssVars : { + filledCustomPropName : '--full' + }, + + selector : { + icon : '.icon' + }, + + templates: { + icon: function(maxRating, iconClass) { + var + icon = 1, + html = '' + ; + while(icon <= maxRating) { + html += '<i class="'+iconClass+' icon"></i>'; + icon++; + } + return html; + } + } + +}; + +})( jQuery, window, document ); diff --git a/semantic/src/definitions/modules/rating.less b/semantic/src/definitions/modules/rating.less new file mode 100644 index 0000000..de95043 --- /dev/null +++ b/semantic/src/definitions/modules/rating.less @@ -0,0 +1,177 @@ +/*! + * # Fomantic-UI - Rating + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + + +/******************************* + Theme +*******************************/ + +@type : 'module'; +@element : 'rating'; + +@import (multiple) '../../theme.config'; + +/******************************* + Rating +*******************************/ + +.ui.rating { + display: inline-flex; + white-space: @whiteSpace; + vertical-align: @verticalAlign; +} +.ui.rating:last-child { + margin-right: 0; +} + +/* Icon */ +.ui.rating .icon { + padding: 0; + margin: 0; + text-align: center; + font-weight: @normal; + font-style: normal; + flex: 1 0 auto; + cursor: @iconCursor; + width: @iconWidth; + height: @iconHeight; + transition: @iconTransition; + line-height: 1; + backface-visibility: hidden; +} + + +/******************************* + Types +*******************************/ + + +/*------------------- + Standard +--------------------*/ + +/* Inactive Icon */ +.ui.rating .icon { + background: @inactiveBackground; + color: @inactiveColor; +} + +/* Active Icon */ +.ui.rating .active.icon { + background: @activeBackground; + color: @activeColor; +} + +/* Partially Active Icon */ +.ui.rating .icon.partial.active { + background: linear-gradient(to right, @activeColor 0% var(--full), @inactiveColor var(--full) 100%); + background-clip: text; + color: transparent; +} + +/* Selected Icon */ +.ui.rating .icon.selected, +.ui.rating .icon.selected.active, +.ui.rating .icon.selected.partial.active { + background: @selectedBackground; + color: @selectedColor; + background-clip: unset; +} + +/*-------------- + Colors +-------------- */ + +each(@colors, { + @color: replace(@key, '@', ''); + @c: @colors[@@color][color]; + @l: @colors[@@color][light]; + @h: @colors[@@color][hover]; + @lh: @colors[@@color][lightHover]; + + .ui.@{color}.rating .active.icon { + color: @l; + text-shadow: 0px -@shadowWidth 0px @c, + -@shadowWidth 0px 0px @c, + 0px @shadowWidth 0px @c, + @shadowWidth 0px 0px @c; + } + .ui.@{color}.rating .icon.selected, + .ui.@{color}.rating .icon.selected.active, + .ui.@{color}.rating .icon.selected.partial.active { + background: inherit; + color: @lh; + text-shadow: 0px -@shadowWidth 0px @h, + -@shadowWidth 0px 0px @h, + 0px @shadowWidth 0px @h, + @shadowWidth 0px 0px @h; + + -webkit-text-stroke: unset; + background-clip: unset; + } + .ui.@{color}.rating .icon.partial.active { + background: linear-gradient(to right, @l 0% var(--full), @inactiveColor var(--full) 100%); + text-shadow: none; + -webkit-text-stroke: @c 0.78px; + background-clip: text; + color: transparent; + } +}) + + +/******************************* + States +*******************************/ + +& when (@variationRatingDisabled) { + /*------------------- + Disabled + --------------------*/ + + /* disabled rating */ + .ui.disabled.rating .icon { + cursor: default; + } +} + + +/*------------------- + User Interactive +--------------------*/ + +/* Selected Rating */ +.ui.rating.selected .active.icon { + opacity: @interactiveActiveIconOpacity; +} +.ui.rating.selected .icon.selected, +.ui.rating .icon.selected { + opacity: @interactiveSelectedIconOpacity; +} + + + +/******************************* + Variations +*******************************/ + +.ui.rating { + font-size: @medium; +} +& when not (@variationRatingSizes = false) { + each(@variationRatingSizes, { + @s: @@value; + .ui.@{value}.rating { + font-size: @s; + } + }) +} + + +.loadUIOverrides(); diff --git a/semantic/src/definitions/modules/search.js b/semantic/src/definitions/modules/search.js new file mode 100644 index 0000000..6f2c7ee --- /dev/null +++ b/semantic/src/definitions/modules/search.js @@ -0,0 +1,1565 @@ +/*! + * # Fomantic-UI - Search + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +'use strict'; + +$.isFunction = $.isFunction || function(obj) { + return typeof obj === "function" && typeof obj.nodeType !== "number"; +}; + +window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.fn.search = 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), + returnedValue + ; + $(this) + .each(function() { + var + settings = ( $.isPlainObject(parameters) ) + ? $.extend(true, {}, $.fn.search.settings, parameters) + : $.extend({}, $.fn.search.settings), + + className = settings.className, + metadata = settings.metadata, + regExp = settings.regExp, + fields = settings.fields, + selector = settings.selector, + error = settings.error, + namespace = settings.namespace, + + eventNamespace = '.' + namespace, + moduleNamespace = namespace + '-module', + + $module = $(this), + $prompt = $module.find(selector.prompt), + $searchButton = $module.find(selector.searchButton), + $results = $module.find(selector.results), + $result = $module.find(selector.result), + $category = $module.find(selector.category), + + element = this, + instance = $module.data(moduleNamespace), + + disabledBubbled = false, + resultsDismissed = false, + + module + ; + + module = { + + initialize: function() { + module.verbose('Initializing module'); + module.get.settings(); + module.determine.searchFields(); + module.bind.events(); + module.set.type(); + module.create.results(); + module.instantiate(); + }, + instantiate: function() { + module.verbose('Storing instance of module', module); + instance = module; + $module + .data(moduleNamespace, module) + ; + }, + destroy: function() { + module.verbose('Destroying instance'); + $module + .off(eventNamespace) + .removeData(moduleNamespace) + ; + }, + + refresh: function() { + module.debug('Refreshing selector cache'); + $prompt = $module.find(selector.prompt); + $searchButton = $module.find(selector.searchButton); + $category = $module.find(selector.category); + $results = $module.find(selector.results); + $result = $module.find(selector.result); + }, + + refreshResults: function() { + $results = $module.find(selector.results); + $result = $module.find(selector.result); + }, + + bind: { + events: function() { + module.verbose('Binding events to search'); + if(settings.automatic) { + $module + .on(module.get.inputEvent() + eventNamespace, selector.prompt, module.event.input) + ; + $prompt + .attr('autocomplete', 'off') + ; + } + $module + // prompt + .on('focus' + eventNamespace, selector.prompt, module.event.focus) + .on('blur' + eventNamespace, selector.prompt, module.event.blur) + .on('keydown' + eventNamespace, selector.prompt, module.handleKeyboard) + // search button + .on('click' + eventNamespace, selector.searchButton, module.query) + // results + .on('mousedown' + eventNamespace, selector.results, module.event.result.mousedown) + .on('mouseup' + eventNamespace, selector.results, module.event.result.mouseup) + .on('click' + eventNamespace, selector.result, module.event.result.click) + ; + } + }, + + determine: { + searchFields: function() { + // this makes sure $.extend does not add specified search fields to default fields + // this is the only setting which should not extend defaults + if(parameters && parameters.searchFields !== undefined) { + settings.searchFields = parameters.searchFields; + } + } + }, + + event: { + input: function() { + if(settings.searchDelay) { + clearTimeout(module.timer); + module.timer = setTimeout(function() { + if(module.is.focused()) { + module.query(); + } + }, settings.searchDelay); + } + else { + module.query(); + } + }, + focus: function() { + module.set.focus(); + if(settings.searchOnFocus && module.has.minimumCharacters() ) { + module.query(function() { + if(module.can.show() ) { + module.showResults(); + } + }); + } + }, + blur: function(event) { + var + pageLostFocus = (document.activeElement === this), + callback = function() { + module.cancel.query(); + module.remove.focus(); + module.timer = setTimeout(module.hideResults, settings.hideDelay); + } + ; + if(pageLostFocus) { + return; + } + resultsDismissed = false; + if(module.resultsClicked) { + module.debug('Determining if user action caused search to close'); + $module + .one('click.close' + eventNamespace, selector.results, function(event) { + if(module.is.inMessage(event) || disabledBubbled) { + $prompt.focus(); + return; + } + disabledBubbled = false; + if( !module.is.animating() && !module.is.hidden()) { + callback(); + } + }) + ; + } + else { + module.debug('Input blurred without user action, closing results'); + callback(); + } + }, + result: { + mousedown: function() { + module.resultsClicked = true; + }, + mouseup: function() { + module.resultsClicked = false; + }, + click: function(event) { + module.debug('Search result selected'); + var + $result = $(this), + $title = $result.find(selector.title).eq(0), + $link = $result.is('a[href]') + ? $result + : $result.find('a[href]').eq(0), + href = $link.attr('href') || false, + target = $link.attr('target') || false, + // title is used for result lookup + value = ($title.length > 0) + ? $title.text() + : false, + results = module.get.results(), + result = $result.data(metadata.result) || module.get.result(value, results) + ; + if(value) { + module.set.value(value); + } + if( $.isFunction(settings.onSelect) ) { + if(settings.onSelect.call(element, result, results) === false) { + module.debug('Custom onSelect callback cancelled default select action'); + disabledBubbled = true; + return; + } + } + module.hideResults(); + if(href) { + event.preventDefault(); + module.verbose('Opening search link found in result', $link); + if(target == '_blank' || event.ctrlKey) { + window.open(href); + } + else { + window.location.href = (href); + } + } + } + } + }, + ensureVisible: function ensureVisible($el) { + var elTop, elBottom, resultsScrollTop, resultsHeight; + + elTop = $el.position().top; + elBottom = elTop + $el.outerHeight(true); + + resultsScrollTop = $results.scrollTop(); + resultsHeight = $results.height() + parseInt($results.css('paddingTop'), 0) + + parseInt($results.css('paddingBottom'), 0); + + if (elTop < 0) { + $results.scrollTop(resultsScrollTop + elTop); + } + + else if (resultsHeight < elBottom) { + $results.scrollTop(resultsScrollTop + (elBottom - resultsHeight)); + } + }, + handleKeyboard: function(event) { + var + // force selector refresh + $result = $module.find(selector.result), + $category = $module.find(selector.category), + $activeResult = $result.filter('.' + className.active), + currentIndex = $result.index( $activeResult ), + resultSize = $result.length, + hasActiveResult = $activeResult.length > 0, + + keyCode = event.which, + keys = { + backspace : 8, + enter : 13, + escape : 27, + upArrow : 38, + downArrow : 40 + }, + newIndex + ; + // search shortcuts + if(keyCode == keys.escape) { + module.verbose('Escape key pressed, blurring search field'); + module.hideResults(); + resultsDismissed = true; + } + if( module.is.visible() ) { + if(keyCode == keys.enter) { + module.verbose('Enter key pressed, selecting active result'); + if( $result.filter('.' + className.active).length > 0 ) { + module.event.result.click.call($result.filter('.' + className.active), event); + event.preventDefault(); + return false; + } + } + else if(keyCode == keys.upArrow && hasActiveResult) { + module.verbose('Up key pressed, changing active result'); + newIndex = (currentIndex - 1 < 0) + ? currentIndex + : currentIndex - 1 + ; + $category + .removeClass(className.active) + ; + $result + .removeClass(className.active) + .eq(newIndex) + .addClass(className.active) + .closest($category) + .addClass(className.active) + ; + module.ensureVisible($result.eq(newIndex)); + event.preventDefault(); + } + else if(keyCode == keys.downArrow) { + module.verbose('Down key pressed, changing active result'); + newIndex = (currentIndex + 1 >= resultSize) + ? currentIndex + : currentIndex + 1 + ; + $category + .removeClass(className.active) + ; + $result + .removeClass(className.active) + .eq(newIndex) + .addClass(className.active) + .closest($category) + .addClass(className.active) + ; + module.ensureVisible($result.eq(newIndex)); + event.preventDefault(); + } + } + else { + // query shortcuts + if(keyCode == keys.enter) { + module.verbose('Enter key pressed, executing query'); + module.query(); + module.set.buttonPressed(); + $prompt.one('keyup', module.remove.buttonFocus); + } + } + }, + + setup: { + api: function(searchTerm, callback) { + var + apiSettings = { + debug : settings.debug, + on : false, + cache : settings.cache, + action : 'search', + urlData : { + query : searchTerm + }, + onSuccess : function(response) { + module.parse.response.call(element, response, searchTerm); + callback(); + }, + onFailure : function() { + module.displayMessage(error.serverError); + callback(); + }, + onAbort : function(response) { + }, + onError : module.error + } + ; + $.extend(true, apiSettings, settings.apiSettings); + module.verbose('Setting up API request', apiSettings); + $module.api(apiSettings); + } + }, + + can: { + useAPI: function() { + return $.fn.api !== undefined; + }, + show: function() { + return module.is.focused() && !module.is.visible() && !module.is.empty(); + }, + transition: function() { + return settings.transition && $.fn.transition !== undefined && $module.transition('is supported'); + } + }, + + is: { + animating: function() { + return $results.hasClass(className.animating); + }, + hidden: function() { + return $results.hasClass(className.hidden); + }, + inMessage: function(event) { + if(!event.target) { + return; + } + var + $target = $(event.target), + isInDOM = $.contains(document.documentElement, event.target) + ; + return (isInDOM && $target.closest(selector.message).length > 0); + }, + empty: function() { + return ($results.html() === ''); + }, + visible: function() { + return ($results.filter(':visible').length > 0); + }, + focused: function() { + return ($prompt.filter(':focus').length > 0); + } + }, + + get: { + settings: function() { + if($.isPlainObject(parameters) && parameters.searchFullText) { + settings.fullTextSearch = parameters.searchFullText; + module.error(settings.error.oldSearchSyntax, element); + } + if (settings.ignoreDiacritics && !String.prototype.normalize) { + settings.ignoreDiacritics = false; + module.error(error.noNormalize, element); + } + }, + inputEvent: function() { + var + prompt = $prompt[0], + inputEvent = (prompt !== undefined && prompt.oninput !== undefined) + ? 'input' + : (prompt !== undefined && prompt.onpropertychange !== undefined) + ? 'propertychange' + : 'keyup' + ; + return inputEvent; + }, + value: function() { + return $prompt.val(); + }, + results: function() { + var + results = $module.data(metadata.results) + ; + return results; + }, + result: function(value, results) { + var + result = false + ; + value = (value !== undefined) + ? value + : module.get.value() + ; + results = (results !== undefined) + ? results + : module.get.results() + ; + if(settings.type === 'category') { + module.debug('Finding result that matches', value); + $.each(results, function(index, category) { + if(Array.isArray(category.results)) { + result = module.search.object(value, category.results)[0]; + // don't continue searching if a result is found + if(result) { + return false; + } + } + }); + } + else { + module.debug('Finding result in results object', value); + result = module.search.object(value, results)[0]; + } + return result || false; + }, + }, + + select: { + firstResult: function() { + module.verbose('Selecting first result'); + $result.first().addClass(className.active); + } + }, + + set: { + focus: function() { + $module.addClass(className.focus); + }, + loading: function() { + $module.addClass(className.loading); + }, + value: function(value) { + module.verbose('Setting search input value', value); + $prompt + .val(value) + ; + }, + type: function(type) { + type = type || settings.type; + if(settings.type == 'category') { + $module.addClass(settings.type); + } + }, + buttonPressed: function() { + $searchButton.addClass(className.pressed); + } + }, + + remove: { + loading: function() { + $module.removeClass(className.loading); + }, + focus: function() { + $module.removeClass(className.focus); + }, + buttonPressed: function() { + $searchButton.removeClass(className.pressed); + }, + diacritics: function(text) { + return settings.ignoreDiacritics ? text.normalize('NFD').replace(/[\u0300-\u036f]/g, '') : text; + } + }, + + query: function(callback) { + callback = $.isFunction(callback) + ? callback + : function(){} + ; + var + searchTerm = module.get.value(), + cache = module.read.cache(searchTerm) + ; + callback = callback || function() {}; + if( module.has.minimumCharacters() ) { + if(cache) { + module.debug('Reading result from cache', searchTerm); + module.save.results(cache.results); + module.addResults(cache.html); + module.inject.id(cache.results); + callback(); + } + else { + module.debug('Querying for', searchTerm); + if($.isPlainObject(settings.source) || Array.isArray(settings.source)) { + module.search.local(searchTerm); + callback(); + } + else if( module.can.useAPI() ) { + module.search.remote(searchTerm, callback); + } + else { + module.error(error.source); + callback(); + } + } + settings.onSearchQuery.call(element, searchTerm); + } + else { + module.hideResults(); + } + }, + + search: { + local: function(searchTerm) { + var + results = module.search.object(searchTerm, settings.source), + searchHTML + ; + module.set.loading(); + module.save.results(results); + module.debug('Returned full local search results', results); + if(settings.maxResults > 0) { + module.debug('Using specified max results', results); + results = results.slice(0, settings.maxResults); + } + if(settings.type == 'category') { + results = module.create.categoryResults(results); + } + searchHTML = module.generateResults({ + results: results + }); + module.remove.loading(); + module.addResults(searchHTML); + module.inject.id(results); + module.write.cache(searchTerm, { + html : searchHTML, + results : results + }); + }, + remote: function(searchTerm, callback) { + callback = $.isFunction(callback) + ? callback + : function(){} + ; + if($module.api('is loading')) { + $module.api('abort'); + } + module.setup.api(searchTerm, callback); + $module + .api('query') + ; + }, + object: function(searchTerm, source, searchFields) { + searchTerm = module.remove.diacritics(String(searchTerm)); + var + results = [], + exactResults = [], + fuzzyResults = [], + searchExp = searchTerm.replace(regExp.escape, '\\$&'), + matchRegExp = new RegExp(regExp.beginsWith + searchExp, 'i'), + + // avoid duplicates when pushing results + addResult = function(array, result) { + var + notResult = ($.inArray(result, results) == -1), + notFuzzyResult = ($.inArray(result, fuzzyResults) == -1), + notExactResults = ($.inArray(result, exactResults) == -1) + ; + if(notResult && notFuzzyResult && notExactResults) { + array.push(result); + } + } + ; + source = source || settings.source; + searchFields = (searchFields !== undefined) + ? searchFields + : settings.searchFields + ; + + // search fields should be array to loop correctly + if(!Array.isArray(searchFields)) { + searchFields = [searchFields]; + } + + // exit conditions if no source + if(source === undefined || source === false) { + module.error(error.source); + return []; + } + // iterate through search fields looking for matches + $.each(searchFields, function(index, field) { + $.each(source, function(label, content) { + var + fieldExists = (typeof content[field] == 'string') || (typeof content[field] == 'number') + ; + if(fieldExists) { + var text; + if (typeof content[field] === 'string'){ + text = module.remove.diacritics(content[field]); + } else { + text = content[field].toString(); + } + if( text.search(matchRegExp) !== -1) { + // content starts with value (first in results) + addResult(results, content); + } + else if(settings.fullTextSearch === 'exact' && module.exactSearch(searchTerm, text) ) { + // content fuzzy matches (last in results) + addResult(exactResults, content); + } + else if(settings.fullTextSearch == true && module.fuzzySearch(searchTerm, text) ) { + // content fuzzy matches (last in results) + addResult(fuzzyResults, content); + } + } + }); + }); + $.merge(exactResults, fuzzyResults); + $.merge(results, exactResults); + return results; + } + }, + exactSearch: function (query, term) { + query = query.toLowerCase(); + term = term.toLowerCase(); + return term.indexOf(query) > -1; + }, + fuzzySearch: function(query, term) { + var + termLength = term.length, + queryLength = query.length + ; + if(typeof query !== 'string') { + return false; + } + query = query.toLowerCase(); + term = term.toLowerCase(); + if(queryLength > termLength) { + return false; + } + if(queryLength === termLength) { + return (query === term); + } + search: for (var characterIndex = 0, nextCharacterIndex = 0; characterIndex < queryLength; characterIndex++) { + var + queryCharacter = query.charCodeAt(characterIndex) + ; + while(nextCharacterIndex < termLength) { + if(term.charCodeAt(nextCharacterIndex++) === queryCharacter) { + continue search; + } + } + return false; + } + return true; + }, + + parse: { + response: function(response, searchTerm) { + if(Array.isArray(response)){ + var o={}; + o[fields.results]=response; + response = o; + } + var + searchHTML = module.generateResults(response) + ; + module.verbose('Parsing server response', response); + if(response !== undefined) { + if(searchTerm !== undefined && response[fields.results] !== undefined) { + module.addResults(searchHTML); + module.inject.id(response[fields.results]); + module.write.cache(searchTerm, { + html : searchHTML, + results : response[fields.results] + }); + module.save.results(response[fields.results]); + } + } + } + }, + + cancel: { + query: function() { + if( module.can.useAPI() ) { + $module.api('abort'); + } + } + }, + + has: { + minimumCharacters: function() { + var + searchTerm = module.get.value(), + numCharacters = searchTerm.length + ; + return (numCharacters >= settings.minCharacters); + }, + results: function() { + if($results.length === 0) { + return false; + } + var + html = $results.html() + ; + return html != ''; + } + }, + + clear: { + cache: function(value) { + var + cache = $module.data(metadata.cache) + ; + if(!value) { + module.debug('Clearing cache', value); + $module.removeData(metadata.cache); + } + else if(value && cache && cache[value]) { + module.debug('Removing value from cache', value); + delete cache[value]; + $module.data(metadata.cache, cache); + } + } + }, + + read: { + cache: function(name) { + var + cache = $module.data(metadata.cache) + ; + if(settings.cache) { + module.verbose('Checking cache for generated html for query', name); + return (typeof cache == 'object') && (cache[name] !== undefined) + ? cache[name] + : false + ; + } + return false; + } + }, + + create: { + categoryResults: function(results) { + var + categoryResults = {} + ; + $.each(results, function(index, result) { + if(!result.category) { + return; + } + if(categoryResults[result.category] === undefined) { + module.verbose('Creating new category of results', result.category); + categoryResults[result.category] = { + name : result.category, + results : [result] + }; + } + else { + categoryResults[result.category].results.push(result); + } + }); + return categoryResults; + }, + id: function(resultIndex, categoryIndex) { + var + resultID = (resultIndex + 1), // not zero indexed + letterID, + id + ; + if(categoryIndex !== undefined) { + // start char code for "A" + letterID = String.fromCharCode(97 + categoryIndex); + id = letterID + resultID; + module.verbose('Creating category result id', id); + } + else { + id = resultID; + module.verbose('Creating result id', id); + } + return id; + }, + results: function() { + if($results.length === 0) { + $results = $('<div />') + .addClass(className.results) + .appendTo($module) + ; + } + } + }, + + inject: { + result: function(result, resultIndex, categoryIndex) { + module.verbose('Injecting result into results'); + var + $selectedResult = (categoryIndex !== undefined) + ? $results + .children().eq(categoryIndex) + .children(selector.results) + .first() + .children(selector.result) + .eq(resultIndex) + : $results + .children(selector.result).eq(resultIndex) + ; + module.verbose('Injecting results metadata', $selectedResult); + $selectedResult + .data(metadata.result, result) + ; + }, + id: function(results) { + module.debug('Injecting unique ids into results'); + var + // since results may be object, we must use counters + categoryIndex = 0, + resultIndex = 0 + ; + if(settings.type === 'category') { + // iterate through each category result + $.each(results, function(index, category) { + if(category.results.length > 0){ + resultIndex = 0; + $.each(category.results, function(index, result) { + if(result.id === undefined) { + result.id = module.create.id(resultIndex, categoryIndex); + } + module.inject.result(result, resultIndex, categoryIndex); + resultIndex++; + }); + categoryIndex++; + } + }); + } + else { + // top level + $.each(results, function(index, result) { + if(result.id === undefined) { + result.id = module.create.id(resultIndex); + } + module.inject.result(result, resultIndex); + resultIndex++; + }); + } + return results; + } + }, + + save: { + results: function(results) { + module.verbose('Saving current search results to metadata', results); + $module.data(metadata.results, results); + } + }, + + write: { + cache: function(name, value) { + var + cache = ($module.data(metadata.cache) !== undefined) + ? $module.data(metadata.cache) + : {} + ; + if(settings.cache) { + module.verbose('Writing generated html to cache', name, value); + cache[name] = value; + $module + .data(metadata.cache, cache) + ; + } + } + }, + + addResults: function(html) { + if( $.isFunction(settings.onResultsAdd) ) { + if( settings.onResultsAdd.call($results, html) === false ) { + module.debug('onResultsAdd callback cancelled default action'); + return false; + } + } + if(html) { + $results + .html(html) + ; + module.refreshResults(); + if(settings.selectFirstResult) { + module.select.firstResult(); + } + module.showResults(); + } + else { + module.hideResults(function() { + $results.empty(); + }); + } + }, + + showResults: function(callback) { + callback = $.isFunction(callback) + ? callback + : function(){} + ; + if(resultsDismissed) { + return; + } + if(!module.is.visible() && module.has.results()) { + if( module.can.transition() ) { + module.debug('Showing results with css animations'); + $results + .transition({ + animation : settings.transition + ' in', + debug : settings.debug, + verbose : settings.verbose, + duration : settings.duration, + onShow : function() { + var $firstResult = $module.find(selector.result).eq(0); + if($firstResult.length > 0) { + module.ensureVisible($firstResult); + } + }, + onComplete : function() { + callback(); + }, + queue : true + }) + ; + } + else { + module.debug('Showing results with javascript'); + $results + .stop() + .fadeIn(settings.duration, settings.easing) + ; + } + settings.onResultsOpen.call($results); + } + }, + hideResults: function(callback) { + callback = $.isFunction(callback) + ? callback + : function(){} + ; + if( module.is.visible() ) { + if( module.can.transition() ) { + module.debug('Hiding results with css animations'); + $results + .transition({ + animation : settings.transition + ' out', + debug : settings.debug, + verbose : settings.verbose, + duration : settings.duration, + onComplete : function() { + callback(); + }, + queue : true + }) + ; + } + else { + module.debug('Hiding results with javascript'); + $results + .stop() + .fadeOut(settings.duration, settings.easing) + ; + } + settings.onResultsClose.call($results); + } + }, + + generateResults: function(response) { + module.debug('Generating html from response', response); + var + template = settings.templates[settings.type], + isProperObject = ($.isPlainObject(response[fields.results]) && !$.isEmptyObject(response[fields.results])), + isProperArray = (Array.isArray(response[fields.results]) && response[fields.results].length > 0), + html = '' + ; + if(isProperObject || isProperArray ) { + if(settings.maxResults > 0) { + if(isProperObject) { + if(settings.type == 'standard') { + module.error(error.maxResults); + } + } + else { + response[fields.results] = response[fields.results].slice(0, settings.maxResults); + } + } + if($.isFunction(template)) { + html = template(response, fields, settings.preserveHTML); + } + else { + module.error(error.noTemplate, false); + } + } + else if(settings.showNoResults) { + html = module.displayMessage(error.noResults, 'empty', error.noResultsHeader); + } + settings.onResults.call(element, response); + return html; + }, + + displayMessage: function(text, type, header) { + type = type || 'standard'; + module.debug('Displaying message', text, type, header); + module.addResults( settings.templates.message(text, type, header) ); + return settings.templates.message(text, type, header); + }, + + setting: function(name, value) { + if( $.isPlainObject(name) ) { + $.extend(true, settings, name); + } + else if(value !== undefined) { + 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($allModules.length > 1) { + title += ' ' + '(' + $allModules.length + ')'; + } + 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 { + return false; + } + }); + } + if( $.isFunction( found ) ) { + response = found.apply(context, passedArguments); + } + else if(found !== undefined) { + response = found; + } + if(Array.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.search.settings = { + + name : 'Search', + namespace : 'search', + + silent : false, + debug : false, + verbose : false, + performance : true, + + // template to use (specified in settings.templates) + type : 'standard', + + // minimum characters required to search + minCharacters : 1, + + // whether to select first result after searching automatically + selectFirstResult : false, + + // API config + apiSettings : false, + + // object to search + source : false, + + // Whether search should query current term on focus + searchOnFocus : true, + + // fields to search + searchFields : [ + 'id', + 'title', + 'description' + ], + + // field to display in standard results template + displayField : '', + + // search anywhere in value (set to 'exact' to require exact matches + fullTextSearch : 'exact', + + // match results also if they contain diacritics of the same base character (for example searching for "a" will also match "á" or "â" or "à ", etc...) + ignoreDiacritics : false, + + // whether to add events to prompt automatically + automatic : true, + + // delay before hiding menu after blur + hideDelay : 0, + + // delay before searching + searchDelay : 200, + + // maximum results returned from search + maxResults : 7, + + // whether to store lookups in local cache + cache : true, + + // whether no results errors should be shown + showNoResults : true, + + // preserve possible html of resultset values + preserveHTML : true, + + // transition settings + transition : 'scale', + duration : 200, + easing : 'easeOutExpo', + + // callbacks + onSelect : false, + onResultsAdd : false, + + onSearchQuery : function(query){}, + onResults : function(response){}, + + onResultsOpen : function(){}, + onResultsClose : function(){}, + + className: { + animating : 'animating', + active : 'active', + empty : 'empty', + focus : 'focus', + hidden : 'hidden', + loading : 'loading', + results : 'results', + pressed : 'down' + }, + + error : { + source : 'Cannot search. No source used, and Semantic API module was not included', + noResultsHeader : 'No Results', + noResults : 'Your search returned no results', + logging : 'Error in debug logging, exiting.', + noEndpoint : 'No search endpoint was specified', + noTemplate : 'A valid template name was not specified.', + oldSearchSyntax : 'searchFullText setting has been renamed fullTextSearch for consistency, please adjust your settings.', + serverError : 'There was an issue querying the server.', + maxResults : 'Results must be an array to use maxResults setting', + method : 'The method you called is not defined.', + noNormalize : '"ignoreDiacritics" setting will be ignored. Browser does not support String().normalize(). You may consider including <https://cdn.jsdelivr.net/npm/[email protected]/lib/unorm.min.js> as a polyfill.' + }, + + metadata: { + cache : 'cache', + results : 'results', + result : 'result' + }, + + regExp: { + escape : /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, + beginsWith : '(?:\s|^)' + }, + + // maps api response attributes to internal representation + fields: { + categories : 'results', // array of categories (category view) + categoryName : 'name', // name of category (category view) + categoryResults : 'results', // array of results (category view) + description : 'description', // result description + image : 'image', // result image + price : 'price', // result price + results : 'results', // array of results (standard) + title : 'title', // result title + url : 'url', // result url + action : 'action', // "view more" object name + actionText : 'text', // "view more" text + actionURL : 'url' // "view more" url + }, + + selector : { + prompt : '.prompt', + searchButton : '.search.button', + results : '.results', + message : '.results > .message', + category : '.category', + result : '.result', + title : '.title, .name' + }, + + templates: { + escape: function(string, preserveHTML) { + if (preserveHTML){ + return string; + } + var + badChars = /[<>"'`]/g, + shouldEscape = /[&<>"'`]/, + escape = { + "<": "<", + ">": ">", + '"': """, + "'": "'", + "`": "`" + }, + escapedChar = function(chr) { + return escape[chr]; + } + ; + if(shouldEscape.test(string)) { + string = string.replace(/&(?![a-z0-9#]{1,6};)/, "&"); + return string.replace(badChars, escapedChar); + } + return string; + }, + message: function(message, type, header) { + var + html = '' + ; + if(message !== undefined && type !== undefined) { + html += '' + + '<div class="message ' + type + '">' + ; + if(header) { + html += '' + + '<div class="header">' + header + '</div>' + ; + } + html += ' <div class="description">' + message + '</div>'; + html += '</div>'; + } + return html; + }, + category: function(response, fields, preserveHTML) { + var + html = '', + escape = $.fn.search.settings.templates.escape + ; + if(response[fields.categoryResults] !== undefined) { + + // each category + $.each(response[fields.categoryResults], function(index, category) { + if(category[fields.results] !== undefined && category.results.length > 0) { + + html += '<div class="category">'; + + if(category[fields.categoryName] !== undefined) { + html += '<div class="name">' + escape(category[fields.categoryName], preserveHTML) + '</div>'; + } + + // each item inside category + html += '<div class="results">'; + $.each(category.results, function(index, result) { + if(result[fields.url]) { + html += '<a class="result" href="' + result[fields.url].replace(/"/g,"") + '">'; + } + else { + html += '<a class="result">'; + } + if(result[fields.image] !== undefined) { + html += '' + + '<div class="image">' + + ' <img src="' + result[fields.image].replace(/"/g,"") + '">' + + '</div>' + ; + } + html += '<div class="content">'; + if(result[fields.price] !== undefined) { + html += '<div class="price">' + escape(result[fields.price], preserveHTML) + '</div>'; + } + if(result[fields.title] !== undefined) { + html += '<div class="title">' + escape(result[fields.title], preserveHTML) + '</div>'; + } + if(result[fields.description] !== undefined) { + html += '<div class="description">' + escape(result[fields.description], preserveHTML) + '</div>'; + } + html += '' + + '</div>' + ; + html += '</a>'; + }); + html += '</div>'; + html += '' + + '</div>' + ; + } + }); + if(response[fields.action]) { + if(fields.actionURL === false) { + html += '' + + '<div class="action">' + + escape(response[fields.action][fields.actionText], preserveHTML) + + '</div>'; + } else { + html += '' + + '<a href="' + response[fields.action][fields.actionURL].replace(/"/g,"") + '" class="action">' + + escape(response[fields.action][fields.actionText], preserveHTML) + + '</a>'; + } + } + return html; + } + return false; + }, + standard: function(response, fields, preserveHTML) { + var + html = '', + escape = $.fn.search.settings.templates.escape + ; + if(response[fields.results] !== undefined) { + + // each result + $.each(response[fields.results], function(index, result) { + if(result[fields.url]) { + html += '<a class="result" href="' + result[fields.url].replace(/"/g,"") + '">'; + } + else { + html += '<a class="result">'; + } + if(result[fields.image] !== undefined) { + html += '' + + '<div class="image">' + + ' <img src="' + result[fields.image].replace(/"/g,"") + '">' + + '</div>' + ; + } + html += '<div class="content">'; + if(result[fields.price] !== undefined) { + html += '<div class="price">' + escape(result[fields.price], preserveHTML) + '</div>'; + } + if(result[fields.title] !== undefined) { + html += '<div class="title">' + escape(result[fields.title], preserveHTML) + '</div>'; + } + if(result[fields.description] !== undefined) { + html += '<div class="description">' + escape(result[fields.description], preserveHTML) + '</div>'; + } + html += '' + + '</div>' + ; + html += '</a>'; + }); + if(response[fields.action]) { + if(fields.actionURL === false) { + html += '' + + '<div class="action">' + + escape(response[fields.action][fields.actionText], preserveHTML) + + '</div>'; + } else { + html += '' + + '<a href="' + response[fields.action][fields.actionURL].replace(/"/g,"") + '" class="action">' + + escape(response[fields.action][fields.actionText], preserveHTML) + + '</a>'; + } + } + return html; + } + return false; + } + } +}; + +})( jQuery, window, document ); diff --git a/semantic/src/definitions/modules/search.less b/semantic/src/definitions/modules/search.less new file mode 100644 index 0000000..e099ea8 --- /dev/null +++ b/semantic/src/definitions/modules/search.less @@ -0,0 +1,560 @@ +/*! + * # Fomantic-UI - Search + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + + +/******************************* + Theme +*******************************/ + +@type : 'module'; +@element : 'search'; + +@import (multiple) '../../theme.config'; + +/******************************* + Search +*******************************/ + +.ui.search { + position: relative; +} + +.ui.search > .prompt { + margin: 0; + outline: none; + -webkit-appearance: none; + -webkit-tap-highlight-color: rgba(255, 255, 255, 0); + + text-shadow: none; + font-style: normal; + font-weight: @normal; + + line-height: @promptLineHeight; + padding: @promptPadding; + font-size: @promptFontSize; + + background: @promptBackground; + border: @promptBorder; + color: @promptColor; + box-shadow: @promptBoxShadow; + transition: @promptTransition; +} + +.ui.search .prompt { + border-radius: @promptBorderRadius; +} + + +/*-------------- + Icon +---------------*/ + +.ui.search .prompt ~ .search.icon { + cursor: pointer; +} + +/*-------------- + Results +---------------*/ + +.ui.search > .results { + display: none; + + position: absolute; + top: 100%; + left: 0; + transform-origin: center top; + white-space: normal; + text-align: left; + text-transform: none; + + background: @resultsBackground; + + margin-top: @resultsDistance; + width: @resultsWidth; + + border-radius: @resultsBorderRadius; + box-shadow: @resultsBoxShadow; + border: @resultsBorder; + z-index: @resultsZIndex; +} +.ui.search > .results > :first-child { + border-radius: @resultsBorderRadius @resultsBorderRadius 0 0; +} +.ui.search > .results > :last-child { + border-radius: 0 0 @resultsBorderRadius @resultsBorderRadius; +} + +/*-------------- + Result +---------------*/ + +.ui.search > .results .result { + cursor: pointer; + display: block; + overflow: hidden; + font-size: @resultFontSize; + padding: @resultPadding; + color: @resultTextColor; + line-height: @resultLineHeight; + border-bottom: @resultDivider; +} +.ui.search > .results .result:last-child { + border-bottom: @resultLastDivider !important; +} + +/* Image */ +.ui.search > .results .result .image { + float: @resultImageFloat; + overflow: hidden; + background: @resultImageBackground; + width: @resultImageWidth; + height: @resultImageHeight; + border-radius: @resultImageBorderRadius; +} +.ui.search > .results .result .image img { + display: block; + width: auto; + height: 100%; +} + +/*-------------- + Info +---------------*/ + +.ui.search > .results .result .image + .content { + margin: @resultImageMargin; +} + +.ui.search > .results .result .title { + margin: @resultTitleMargin; + font-family: @resultTitleFont; + font-weight: @resultTitleFontWeight; + font-size: @resultTitleFontSize; + color: @resultTitleColor; +} +.ui.search > .results .result .description { + margin-top: @resultDescriptionDistance; + font-size: @resultDescriptionFontSize; + color: @resultDescriptionColor; +} +.ui.search > .results .result .price { + float: @resultPriceFloat; + color: @resultPriceColor; +} + +/*-------------- + Message +---------------*/ + +.ui.search > .results > .message { + padding: @messageVerticalPadding @messageHorizontalPadding; +} +.ui.search > .results > .message .header { + font-family: @headerFont; + font-size: @messageHeaderFontSize; + font-weight: @messageHeaderFontWeight; + color: @messageHeaderColor; +} +.ui.search > .results > .message .description { + margin-top: @messageDescriptionDistance; + font-size: @messageDescriptionFontSize; + color: @messageDescriptionColor; +} + +/* View All Results */ +.ui.search > .results > .action { + display: block; + border-top: @actionBorder; + background: @actionBackground; + padding: @actionPadding; + color: @actionColor; + font-weight: @actionFontWeight; + text-align: @actionAlign; +} + + +/******************************* + States +*******************************/ + +/*-------------------- + Focus +---------------------*/ + +.ui.search > .prompt:focus { + border-color: @promptFocusBorderColor; + background: @promptFocusBackground; + color: @promptFocusColor; +} + +& when (@variationSearchLoading) { + /*-------------------- + Loading + ---------------------*/ + + .ui.loading.search .input > i.icon:before { + position: absolute; + content: ''; + top: 50%; + left: 50%; + + margin: @loaderMargin; + width: @loaderSize; + height: @loaderSize; + + border-radius: @circularRadius; + border: @loaderLineWidth solid @loaderFillColor; + } + .ui.loading.search .input > i.icon:after { + position: absolute; + content: ''; + top: 50%; + left: 50%; + + margin: @loaderMargin; + width: @loaderSize; + height: @loaderSize; + + animation: loader @loaderSpeed infinite linear; + border: @loaderLineWidth solid @loaderLineColor; + border-radius: @circularRadius; + + box-shadow: 0 0 0 1px transparent; + } +} + + +/*-------------- + Hover +---------------*/ + +.ui.search > .results .result:hover, +.ui.category.search > .results .category .result:hover { + background: @resultHoverBackground; +} +.ui.search .action:hover:not(div) { + background: @actionHoverBackground; +} + +/*-------------- + Active +---------------*/ +& when (@variationSearchCategory) { + .ui.category.search > .results .category.active { + background: @categoryActiveBackground; + } + .ui.category.search > .results .category.active > .name { + color: @categoryNameActiveColor; + } +} + +.ui.search > .results .result.active, +.ui.category.search > .results .category .result.active { + position: relative; + border-left-color: @resultActiveBorderLeft; + background: @resultActiveBackground; + box-shadow: @resultActiveBoxShadow; +} +.ui.search > .results .result.active .title { + color: @resultActiveTitleColor; +} +.ui.search > .results .result.active .description { + color: @resultActiveDescriptionColor; +} + +& when (@variationSearchDisabled) { + /*-------------------- + Disabled + ----------------------*/ + + /* Disabled */ + .ui.disabled.search { + cursor: default; + pointer-events: none; + opacity: @disabledOpacity; + } +} + + +/******************************* + Types +*******************************/ + +& when (@variationSearchSelection) { + /*-------------- + Selection + ---------------*/ + + .ui.search.selection .prompt { + border-radius: @selectionPromptBorderRadius; + } + + /* Remove input */ + .ui.search.selection > .icon.input > .remove.icon { + pointer-events: none; + position: absolute; + left: auto; + opacity: 0; + color: @selectionCloseIconColor; + top: @selectionCloseTop; + right: @selectionCloseRight; + transition: @selectionCloseTransition; + } + .ui.search.selection > .icon.input > .active.remove.icon { + cursor: pointer; + opacity: @selectionCloseIconOpacity; + pointer-events: auto; + } + .ui.search.selection > .icon.input:not([class*="left icon"]) > .icon ~ .remove.icon { + right: @selectionCloseIconInputRight; + } + .ui.search.selection > .icon.input > .remove.icon:hover { + opacity: @selectionCloseIconHoverOpacity; + color: @selectionCloseIconHoverColor; + } +} + +& when (@variationSearchCategory) { + /*-------------- + Category + ---------------*/ + + .ui.category.search .results { + width: @categoryResultsWidth; + } + + .ui.category.search .results.animating, + .ui.category.search .results.visible { + display: table; + } + + /* Category */ + .ui.category.search > .results .category { + display: table-row; + background: @categoryBackground; + box-shadow: @categoryBoxShadow; + transition: @categoryTransition; + } + + /* Last Category */ + .ui.category.search > .results .category:last-child { + border-bottom: none; + } + + /* First / Last */ + .ui.category.search > .results .category:first-child .name + .result { + border-radius: 0 @resultsBorderRadius 0 0; + } + .ui.category.search > .results .category:last-child .result:last-child { + border-radius: 0 0 @resultsBorderRadius 0; + } + + /* Category Result Name */ + .ui.category.search > .results .category > .name { + display: table-cell; + text-overflow: ellipsis; + width: @categoryNameWidth; + white-space: @categoryNameWhitespace; + background: @categoryNameBackground; + font-family: @categoryNameFont; + font-size: @categoryNameFontSize; + padding: @categoryNamePadding; + font-weight: @categoryNameFontWeight; + color: @categoryNameColor; + border-bottom: @categoryDivider; + } + + /* Category Result */ + .ui.category.search > .results .category .results { + display: table-cell; + background: @categoryResultBackground; + border-left: @categoryResultLeftBorder; + border-bottom: @categoryDivider; + } + .ui.category.search > .results .category .result { + border-bottom: @categoryResultDivider; + transition: @categoryResultTransition; + padding: @categoryResultPadding; + } +} + +/******************************* + Variations +*******************************/ + +& when (@variationSearchScrolling), + (@variationSearchShort), + (@variationSearchLong) { + + /*------------------- + Scrolling + --------------------*/ + + .ui.scrolling.search > .results, + .ui.search.long > .results, + .ui.search.short > .results { + overflow-x: hidden; + overflow-y: auto; + backface-visibility: hidden; + -webkit-overflow-scrolling: touch; + } +} + + +& when (@variationSearchScrolling) { + @media only screen and (max-width : @largestMobileScreen) { + .ui.scrolling.search > .results { + max-height: @scrollingMobileMaxResultsHeight; + } + } + @media only screen and (min-width: @tabletBreakpoint) { + .ui.scrolling.search > .results { + max-height: @scrollingTabletMaxResultsHeight; + } + } + @media only screen and (min-width: @computerBreakpoint) { + .ui.scrolling.search > .results { + max-height: @scrollingComputerMaxResultsHeight; + } + } + @media only screen and (min-width: @widescreenMonitorBreakpoint) { + .ui.scrolling.search > .results { + max-height: @scrollingWidescreenMaxResultsHeight; + } + } +} + +@media only screen and (max-width : @largestMobileScreen) { + & when (@variationSearchShort) { + .ui.search.short > .results { + max-height: @scrollingMobileMaxResultsHeight; + } + .ui.search[class*="very short"] > .results { + max-height: @scrollingMobileMaxResultsHeight * 0.75; + } + } + & when (@variationSearchLong) { + .ui.search.long > .results { + max-height: @scrollingMobileMaxResultsHeight * 2; + } + .ui.search[class*="very long"] > .results { + max-height: @scrollingMobileMaxResultsHeight * 3; + } + } +} +@media only screen and (min-width: @tabletBreakpoint) { + & when (@variationSearchShort) { + .ui.search.short > .results { + max-height: @scrollingTabletMaxResultsHeight; + } + .ui.search[class*="very short"] > .results { + max-height: @scrollingTabletMaxResultsHeight * 0.75; + } + } + & when (@variationSearchLong) { + .ui.search.long > .results { + max-height: @scrollingTabletMaxResultsHeight * 2; + } + .ui.search[class*="very long"] > .results { + max-height: @scrollingTabletMaxResultsHeight * 3; + } + } +} +@media only screen and (min-width: @computerBreakpoint) { + & when (@variationSearchShort) { + .ui.search.short > .results { + max-height: @scrollingComputerMaxResultsHeight; + } + .ui.search[class*="very short"] > .results { + max-height: @scrollingComputerMaxResultsHeight * 0.75; + } + } + & when (@variationSearchLong) { + .ui.search.long > .results { + max-height: @scrollingComputerMaxResultsHeight * 2; + } + .ui.search[class*="very long"] > .results { + max-height: @scrollingComputerMaxResultsHeight * 3; + } + } +} +@media only screen and (min-width: @widescreenMonitorBreakpoint) { + & when (@variationSearchShort) { + .ui.search.short > .results { + max-height: @scrollingWidescreenMaxResultsHeight; + } + .ui.search[class*="very short"] > .results { + max-height: @scrollingWidescreenMaxResultsHeight * 0.75; + } + } + & when (@variationSearchLong) { + .ui.search.long > .results { + max-height: @scrollingWidescreenMaxResultsHeight * 2; + } + .ui.search[class*="very long"] > .results { + max-height: @scrollingWidescreenMaxResultsHeight * 3; + } + } +} + +& when (@variationSearchAligned) { + /*------------------- + Left / Right + --------------------*/ + + .ui[class*="left aligned"].search > .results { + right: auto; + left: 0; + } + .ui[class*="right aligned"].search > .results { + right: 0; + left: auto; + } +} + +/*-------------- + Fluid +---------------*/ + +& when (@variationSearchFluid) { + .ui.fluid.search .results { + width: 100%; + } +} + + +/*-------------- + Sizes +---------------*/ + +.ui.search { + font-size: @relativeMedium; +} +& when not (@variationFeedSizes = false) { + each(@variationFeedSizes, { + @s: @{value}SearchSize; + .ui.@{value}.search { + font-size: @@s; + } + }) +} + +/*-------------- + Mobile +---------------*/ + +@media only screen and (max-width: @largestMobileScreen) { + .ui.search .results { + max-width: @mobileMaxWidth; + } +} + +.loadUIOverrides(); diff --git a/semantic/src/definitions/modules/shape.js b/semantic/src/definitions/modules/shape.js new file mode 100644 index 0000000..1c1229a --- /dev/null +++ b/semantic/src/definitions/modules/shape.js @@ -0,0 +1,848 @@ +/*! + * # Fomantic-UI - Shape + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +'use strict'; + +$.isFunction = $.isFunction || function(obj) { + return typeof obj === "function" && typeof obj.nodeType !== "number"; +}; + +window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.fn.shape = function(parameters) { + var + $allModules = $(this), + + time = new Date().getTime(), + performance = [], + + query = arguments[0], + methodInvoked = (typeof query == 'string'), + queryArguments = [].slice.call(arguments, 1), + + requestAnimationFrame = window.requestAnimationFrame + || window.mozRequestAnimationFrame + || window.webkitRequestAnimationFrame + || window.msRequestAnimationFrame + || function(callback) { setTimeout(callback, 0); }, + + returnedValue + ; + + $allModules + .each(function() { + var + moduleSelector = $allModules.selector || '', + settings = ( $.isPlainObject(parameters) ) + ? $.extend(true, {}, $.fn.shape.settings, parameters) + : $.extend({}, $.fn.shape.settings), + + // internal aliases + namespace = settings.namespace, + selector = settings.selector, + error = settings.error, + className = settings.className, + + // define namespaces for modules + eventNamespace = '.' + namespace, + moduleNamespace = 'module-' + namespace, + + // selector cache + $module = $(this), + $sides = $module.find('>' + selector.sides), + $side = $sides.find('>' + selector.side), + + // private variables + nextIndex = false, + $activeSide, + $nextSide, + + // standard module + element = this, + instance = $module.data(moduleNamespace), + module + ; + + module = { + + initialize: function() { + module.verbose('Initializing module for', element); + module.set.defaultSide(); + module.instantiate(); + }, + + instantiate: function() { + module.verbose('Storing instance of module', module); + instance = module; + $module + .data(moduleNamespace, instance) + ; + }, + + destroy: function() { + module.verbose('Destroying previous module for', element); + $module + .removeData(moduleNamespace) + .off(eventNamespace) + ; + }, + + refresh: function() { + module.verbose('Refreshing selector cache for', element); + $module = $(element); + $sides = $(this).find(selector.sides); + $side = $(this).find(selector.side); + }, + + repaint: function() { + module.verbose('Forcing repaint event'); + var + shape = $sides[0] || document.createElement('div'), + fakeAssignment = shape.offsetWidth + ; + }, + + animate: function(propertyObject, callback) { + module.verbose('Animating box with properties', propertyObject); + callback = callback || function(event) { + module.verbose('Executing animation callback'); + if(event !== undefined) { + event.stopPropagation(); + } + module.reset(); + module.set.active(); + }; + settings.beforeChange.call($nextSide[0]); + if(module.get.transitionEvent()) { + module.verbose('Starting CSS animation'); + $module + .addClass(className.animating) + ; + $sides + .css(propertyObject) + .one(module.get.transitionEvent(), callback) + ; + module.set.duration(settings.duration); + requestAnimationFrame(function() { + $module + .addClass(className.animating) + ; + $activeSide + .addClass(className.hidden) + ; + }); + } + else { + callback(); + } + }, + + queue: function(method) { + module.debug('Queueing animation of', method); + $sides + .one(module.get.transitionEvent(), function() { + module.debug('Executing queued animation'); + setTimeout(function(){ + $module.shape(method); + }, 0); + }) + ; + }, + + reset: function() { + module.verbose('Animating states reset'); + $module + .removeClass(className.animating) + .attr('style', '') + .removeAttr('style') + ; + // removeAttr style does not consistently work in safari + $sides + .attr('style', '') + .removeAttr('style') + ; + $side + .attr('style', '') + .removeAttr('style') + .removeClass(className.hidden) + ; + $nextSide + .removeClass(className.animating) + .attr('style', '') + .removeAttr('style') + ; + }, + + is: { + complete: function() { + return ($side.filter('.' + className.active)[0] == $nextSide[0]); + }, + animating: function() { + return $module.hasClass(className.animating); + }, + hidden: function() { + return $module.closest(':hidden').length > 0; + } + }, + + set: { + + defaultSide: function() { + $activeSide = $side.filter('.' + settings.className.active); + $nextSide = ( $activeSide.next(selector.side).length > 0 ) + ? $activeSide.next(selector.side) + : $side.first() + ; + nextIndex = false; + module.verbose('Active side set to', $activeSide); + module.verbose('Next side set to', $nextSide); + }, + + duration: function(duration) { + duration = duration || settings.duration; + duration = (typeof duration == 'number') + ? duration + 'ms' + : duration + ; + module.verbose('Setting animation duration', duration); + if(settings.duration || settings.duration === 0) { + $sides.add($side) + .css({ + '-webkit-transition-duration': duration, + '-moz-transition-duration': duration, + '-ms-transition-duration': duration, + '-o-transition-duration': duration, + 'transition-duration': duration + }) + ; + } + }, + + currentStageSize: function() { + var + $activeSide = $side.filter('.' + settings.className.active), + width = $activeSide.outerWidth(true), + height = $activeSide.outerHeight(true) + ; + $module + .css({ + width: width, + height: height + }) + ; + }, + + stageSize: function() { + var + $clone = $module.clone().addClass(className.loading), + $side = $clone.find('>' + selector.sides + '>' + selector.side), + $activeSide = $side.filter('.' + settings.className.active), + $nextSide = (nextIndex) + ? $side.eq(nextIndex) + : ( $activeSide.next(selector.side).length > 0 ) + ? $activeSide.next(selector.side) + : $side.first(), + newWidth = (settings.width === 'next') + ? $nextSide.outerWidth(true) + : (settings.width === 'initial') + ? $module.width() + : settings.width, + newHeight = (settings.height === 'next') + ? $nextSide.outerHeight(true) + : (settings.height === 'initial') + ? $module.height() + : settings.height + ; + $activeSide.removeClass(className.active); + $nextSide.addClass(className.active); + $clone.insertAfter($module); + $clone.remove(); + if(settings.width !== 'auto') { + $module.css('width', newWidth + settings.jitter); + module.verbose('Specifying width during animation', newWidth); + } + if(settings.height !== 'auto') { + $module.css('height', newHeight + settings.jitter); + module.verbose('Specifying height during animation', newHeight); + } + }, + + nextSide: function(selector) { + nextIndex = selector; + $nextSide = $side.filter(selector); + nextIndex = $side.index($nextSide); + if($nextSide.length === 0) { + module.set.defaultSide(); + module.error(error.side); + } + module.verbose('Next side manually set to', $nextSide); + }, + + active: function() { + module.verbose('Setting new side to active', $nextSide); + $side + .removeClass(className.active) + ; + $nextSide + .addClass(className.active) + ; + settings.onChange.call($nextSide[0]); + module.set.defaultSide(); + } + }, + + flip: { + to: function(type,stage){ + if(module.is.hidden()) { + module.debug('Module not visible', $nextSide); + return; + } + if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) { + module.debug('Side already visible', $nextSide); + return; + } + var + transform = module.get.transform[type]() + ; + if( !module.is.animating()) { + module.debug('Flipping '+type, $nextSide); + module.set.stageSize(); + module.stage[stage](); + module.animate(transform); + } + else { + module.queue('flip '+type); + } + }, + + up: function() { + module.flip.to('up','above'); + }, + + down: function() { + module.flip.to('down','below'); + }, + + left: function() { + module.flip.to('left','left'); + }, + + right: function() { + module.flip.to('right','right'); + }, + + over: function() { + module.flip.to('over','behind'); + }, + + back: function() { + module.flip.to('back','behind'); + } + + }, + + get: { + + transform: { + up: function() { + var + translateZ = $activeSide.outerHeight(true) / 2, + translateY = $nextSide.outerHeight(true) - translateZ + ; + return { + transform: 'translateY(' + translateY + 'px) translateZ(-'+ translateZ + 'px) rotateX(-90deg)' + }; + }, + + down: function() { + var + translate = { + z: $activeSide.outerHeight(true) / 2 + } + ; + return { + transform: 'translateY(-' + translate.z + 'px) translateZ(-'+ translate.z + 'px) rotateX(90deg)' + }; + }, + + left: function() { + var + translateZ = $activeSide.outerWidth(true) / 2, + translateX = $nextSide.outerWidth(true) - translateZ + ; + return { + transform: 'translateX(' + translateX + 'px) translateZ(-' + translateZ + 'px) rotateY(90deg)' + }; + }, + + right: function() { + var + translate = { + z : $activeSide.outerWidth(true) / 2 + } + ; + return { + transform: 'translateX(-' + translate.z + 'px) translateZ(-' + translate.z + 'px) rotateY(-90deg)' + }; + }, + + over: function() { + var + translate = { + x : -(($activeSide.outerWidth(true) - $nextSide.outerWidth(true)) / 2) + } + ; + return { + transform: 'translateX(' + translate.x + 'px) rotateY(180deg)' + }; + }, + + back: function() { + var + translate = { + x : -(($activeSide.outerWidth(true) - $nextSide.outerWidth(true)) / 2) + } + ; + return { + transform: 'translateX(' + translate.x + 'px) rotateY(-180deg)' + }; + } + }, + + transitionEvent: function() { + var + element = document.createElement('element'), + transitions = { + 'transition' :'transitionend', + 'OTransition' :'oTransitionEnd', + 'MozTransition' :'transitionend', + 'WebkitTransition' :'webkitTransitionEnd' + }, + transition + ; + for(transition in transitions){ + if( element.style[transition] !== undefined ){ + return transitions[transition]; + } + } + }, + + nextSide: function() { + return ( $activeSide.next(selector.side).length > 0 ) + ? $activeSide.next(selector.side) + : $side.first() + ; + } + + }, + + stage: { + + above: function() { + var + box = { + origin : (($activeSide.outerHeight(true) - $nextSide.outerHeight(true)) / 2), + depth : { + active : ($nextSide.outerHeight(true) / 2), + next : ($activeSide.outerHeight(true) / 2) + } + } + ; + module.verbose('Setting the initial animation position as above', $nextSide, box); + $activeSide + .css({ + 'transform' : 'rotateX(0deg)' + }) + ; + $nextSide + .addClass(className.animating) + .css({ + 'top' : box.origin + 'px', + 'transform' : 'rotateX(90deg) translateZ(' + box.depth.next + 'px) translateY(-' + box.depth.active + 'px)' + }) + ; + }, + + below: function() { + var + box = { + origin : (($activeSide.outerHeight(true) - $nextSide.outerHeight(true)) / 2), + depth : { + active : ($nextSide.outerHeight(true) / 2), + next : ($activeSide.outerHeight(true) / 2) + } + } + ; + module.verbose('Setting the initial animation position as below', $nextSide, box); + $activeSide + .css({ + 'transform' : 'rotateX(0deg)' + }) + ; + $nextSide + .addClass(className.animating) + .css({ + 'top' : box.origin + 'px', + 'transform' : 'rotateX(-90deg) translateZ(' + box.depth.next + 'px) translateY(' + box.depth.active + 'px)' + }) + ; + }, + + left: function() { + var + height = { + active : $activeSide.outerWidth(true), + next : $nextSide.outerWidth(true) + }, + box = { + origin : ( ( height.active - height.next ) / 2), + depth : { + active : (height.next / 2), + next : (height.active / 2) + } + } + ; + module.verbose('Setting the initial animation position as left', $nextSide, box); + $activeSide + .css({ + 'transform' : 'rotateY(0deg)' + }) + ; + $nextSide + .addClass(className.animating) + .css({ + 'left' : box.origin + 'px', + 'transform' : 'rotateY(-90deg) translateZ(' + box.depth.next + 'px) translateX(-' + box.depth.active + 'px)' + }) + ; + }, + + right: function() { + var + height = { + active : $activeSide.outerWidth(true), + next : $nextSide.outerWidth(true) + }, + box = { + origin : ( ( height.active - height.next ) / 2), + depth : { + active : (height.next / 2), + next : (height.active / 2) + } + } + ; + module.verbose('Setting the initial animation position as right', $nextSide, box); + $activeSide + .css({ + 'transform' : 'rotateY(0deg)' + }) + ; + $nextSide + .addClass(className.animating) + .css({ + 'left' : box.origin + 'px', + 'transform' : 'rotateY(90deg) translateZ(' + box.depth.next + 'px) translateX(' + box.depth.active + 'px)' + }) + ; + }, + + behind: function() { + var + height = { + active : $activeSide.outerWidth(true), + next : $nextSide.outerWidth(true) + }, + box = { + origin : ( ( height.active - height.next ) / 2), + depth : { + active : (height.next / 2), + next : (height.active / 2) + } + } + ; + module.verbose('Setting the initial animation position as behind', $nextSide, box); + $activeSide + .css({ + 'transform' : 'rotateY(0deg)' + }) + ; + $nextSide + .addClass(className.animating) + .css({ + 'left' : box.origin + 'px', + 'transform' : 'rotateY(-180deg)' + }) + ; + } + }, + 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($allModules.length > 1) { + title += ' ' + '(' + $allModules.length + ')'; + } + 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 { + return false; + } + }); + } + if ( $.isFunction( found ) ) { + response = found.apply(context, passedArguments); + } + else if(found !== undefined) { + response = found; + } + if(Array.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(); + } + var $inputs = $module.find('input'); + if( $inputs.length > 0) { + $inputs.blur(); + setTimeout(function(){ + module.invoke(query); + }, 150); + } else { + module.invoke(query); + } + } + else { + if(instance !== undefined) { + instance.invoke('destroy'); + } + module.initialize(); + } + }) + ; + + return (returnedValue !== undefined) + ? returnedValue + : this + ; +}; + +$.fn.shape.settings = { + + // module info + name : 'Shape', + + // hide all debug content + silent : false, + + // debug content outputted to console + debug : false, + + // verbose debug output + verbose : false, + + // fudge factor in pixels when swapping from 2d to 3d (can be useful to correct rounding errors) + jitter : 0, + + // performance data output + performance: true, + + // event namespace + namespace : 'shape', + + // width during animation, can be set to 'auto', initial', 'next' or pixel amount + width: 'initial', + + // height during animation, can be set to 'auto', 'initial', 'next' or pixel amount + height: 'initial', + + // callback occurs on side change + beforeChange : function() {}, + onChange : function() {}, + + // allow animation to same side + allowRepeats: false, + + // animation duration + duration : false, + + // possible errors + error: { + side : 'You tried to switch to a side that does not exist.', + method : 'The method you called is not defined' + }, + + // classnames used + className : { + animating : 'animating', + hidden : 'hidden', + loading : 'loading', + active : 'active' + }, + + // selectors used + selector : { + sides : '.sides', + side : '.side' + } + +}; + + +})( jQuery, window, document ); diff --git a/semantic/src/definitions/modules/shape.less b/semantic/src/definitions/modules/shape.less new file mode 100644 index 0000000..4d0b8ab --- /dev/null +++ b/semantic/src/definitions/modules/shape.less @@ -0,0 +1,155 @@ +/*! + * # Fomantic-UI - Shape + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + + + +/******************************* + Theme +*******************************/ + +@type : 'module'; +@element : 'shape'; + +@import (multiple) '../../theme.config'; + +/******************************* + Shape +*******************************/ + +.ui.shape { + position: relative; + vertical-align: top; + display: @display; + perspective: @perspective; + transition: @transition; +} + +.ui.shape .side, +.ui.shape .sides { + transform-style: preserve-3d; +} + +.ui.shape .side { + display: none; + opacity: 1; + width: 100%; + + margin: @sideMargin !important; + backface-visibility: @backfaceVisibility; +} + +.ui.shape .side * { + backface-visibility: visible !important; +} + +/******************************* + Types +*******************************/ + +& when (@variationShapeCube) { + .ui.cube.shape .side { + min-width: @cubeSize; + height: @cubeSize; + + padding: @cubePadding; + + background-color: @cubeBackground; + color: @cubeTextColor; + box-shadow: @cubeBoxShadow; + } + .ui.cube.shape .side > .content { + width: 100%; + height: 100%; + display: table; + + text-align: @cubeTextAlign; + user-select: text; + } + .ui.cube.shape .side > .content > div { + display: table-cell; + vertical-align: middle; + font-size: @cubeFontSize; + } +} + +/******************************* + Variations +*******************************/ +& when (@variationShapeText) { + .ui.text.shape.animating .sides { + position: static; + } + .ui.text.shape .side { + white-space: nowrap; + } + .ui.text.shape .side > * { + white-space: normal; + } +} + + +/******************************* + States +*******************************/ + +& when (@variationShapeLoading) { + /*-------------- + Loading + ---------------*/ + + .ui.loading.shape { + position: absolute; + top: -9999px; + left: -9999px; + } +} + + +/*-------------- + Animating +---------------*/ + +.ui.shape .animating.side { + position: absolute; + top: 0; + left: 0; + display: block; + z-index: @animatingZIndex; +} +.ui.shape .hidden.side { + opacity: @hiddenSideOpacity; +} + + +/*-------------- + CSS +---------------*/ + +.ui.shape.animating .sides { + position: absolute; + transition: @transition; +} +.ui.shape.animating .side { + transition: @sideTransition; +} +.ui.shape .animating.side *, +.ui.shape.animating .side * { + transition: none; +} + +/*-------------- + Active +---------------*/ + +.ui.shape .active.side { + display: block; +} + +.loadUIOverrides(); diff --git a/semantic/src/definitions/modules/sidebar.js b/semantic/src/definitions/modules/sidebar.js new file mode 100644 index 0000000..ed7105c --- /dev/null +++ b/semantic/src/definitions/modules/sidebar.js @@ -0,0 +1,1036 @@ +/*! + * # Fomantic-UI - Sidebar + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +'use strict'; + +$.isFunction = $.isFunction || function(obj) { + return typeof obj === "function" && typeof obj.nodeType !== "number"; +}; + +window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.fn.sidebar = function(parameters) { + var + $allModules = $(this), + $window = $(window), + $document = $(document), + $html = $('html'), + $head = $('head'), + + moduleSelector = $allModules.selector || '', + + time = new Date().getTime(), + performance = [], + + query = arguments[0], + methodInvoked = (typeof query == 'string'), + queryArguments = [].slice.call(arguments, 1), + + requestAnimationFrame = window.requestAnimationFrame + || window.mozRequestAnimationFrame + || window.webkitRequestAnimationFrame + || window.msRequestAnimationFrame + || function(callback) { setTimeout(callback, 0); }, + + returnedValue + ; + + $allModules + .each(function() { + var + settings = ( $.isPlainObject(parameters) ) + ? $.extend(true, {}, $.fn.sidebar.settings, parameters) + : $.extend({}, $.fn.sidebar.settings), + + selector = settings.selector, + className = settings.className, + namespace = settings.namespace, + regExp = settings.regExp, + error = settings.error, + + eventNamespace = '.' + namespace, + moduleNamespace = 'module-' + namespace, + + $module = $(this), + $context = $(settings.context), + + $sidebars = $module.children(selector.sidebar), + $fixed = $context.children(selector.fixed), + $pusher = $context.children(selector.pusher), + $style, + + element = this, + instance = $module.data(moduleNamespace), + + elementNamespace, + id, + currentScroll, + transitionEvent, + + module + ; + + module = { + + initialize: function() { + module.debug('Initializing sidebar', parameters); + + module.create.id(); + + transitionEvent = module.get.transitionEvent(); + + // avoids locking rendering if initialized in onReady + if(settings.delaySetup) { + requestAnimationFrame(module.setup.layout); + } + else { + module.setup.layout(); + } + + requestAnimationFrame(function() { + module.setup.cache(); + }); + + module.instantiate(); + }, + + instantiate: function() { + module.verbose('Storing instance of module', module); + instance = module; + $module + .data(moduleNamespace, module) + ; + }, + + create: { + id: function() { + id = (Math.random().toString(16) + '000000000').substr(2,8); + elementNamespace = '.' + id; + module.verbose('Creating unique id for element', id); + } + }, + + destroy: function() { + module.verbose('Destroying previous module for', $module); + $module + .off(eventNamespace) + .removeData(moduleNamespace) + ; + if(module.is.ios()) { + module.remove.ios(); + } + // bound by uuid + $context.off(elementNamespace); + $window.off(elementNamespace); + $document.off(elementNamespace); + }, + + event: { + clickaway: function(event) { + if(settings.closable){ + var + clickedInPusher = ($pusher.find(event.target).length > 0 || $pusher.is(event.target)), + clickedContext = ($context.is(event.target)) + ; + if(clickedInPusher) { + module.verbose('User clicked on dimmed page'); + module.hide(); + } + if(clickedContext) { + module.verbose('User clicked on dimmable context (scaled out page)'); + module.hide(); + } + } + }, + touch: function(event) { + //event.stopPropagation(); + }, + containScroll: function(event) { + if(element.scrollTop <= 0) { + element.scrollTop = 1; + } + if((element.scrollTop + element.offsetHeight) >= element.scrollHeight) { + element.scrollTop = element.scrollHeight - element.offsetHeight - 1; + } + }, + scroll: function(event) { + if( $(event.target).closest(selector.sidebar).length === 0 ) { + event.preventDefault(); + } + } + }, + + bind: { + clickaway: function() { + module.verbose('Adding clickaway events to context', $context); + $context + .on('click' + elementNamespace, module.event.clickaway) + .on('touchend' + elementNamespace, module.event.clickaway) + ; + }, + scrollLock: function() { + if(settings.scrollLock) { + module.debug('Disabling page scroll'); + $window + .on('DOMMouseScroll' + elementNamespace, module.event.scroll) + ; + } + module.verbose('Adding events to contain sidebar scroll'); + $document + .on('touchmove' + elementNamespace, module.event.touch) + ; + $module + .on('scroll' + eventNamespace, module.event.containScroll) + ; + } + }, + unbind: { + clickaway: function() { + module.verbose('Removing clickaway events from context', $context); + $context.off(elementNamespace); + }, + scrollLock: function() { + module.verbose('Removing scroll lock from page'); + $document.off(elementNamespace); + $window.off(elementNamespace); + $module.off('scroll' + eventNamespace); + } + }, + + add: { + inlineCSS: function() { + var + width = module.cache.width || $module.outerWidth(), + height = module.cache.height || $module.outerHeight(), + isRTL = module.is.rtl(), + direction = module.get.direction(), + distance = { + left : width, + right : -width, + top : height, + bottom : -height + }, + style + ; + + if(isRTL){ + module.verbose('RTL detected, flipping widths'); + distance.left = -width; + distance.right = width; + } + + style = '<style>'; + + if(direction === 'left' || direction === 'right') { + module.debug('Adding CSS rules for animation distance', width); + style += '' + + ' .ui.visible.' + direction + '.sidebar ~ .fixed,' + + ' .ui.visible.' + direction + '.sidebar ~ .pusher {' + + ' -webkit-transform: translate3d('+ distance[direction] + 'px, 0, 0);' + + ' transform: translate3d('+ distance[direction] + 'px, 0, 0);' + + ' }' + ; + } + else if(direction === 'top' || direction == 'bottom') { + style += '' + + ' .ui.visible.' + direction + '.sidebar ~ .fixed,' + + ' .ui.visible.' + direction + '.sidebar ~ .pusher {' + + ' -webkit-transform: translate3d(0, ' + distance[direction] + 'px, 0);' + + ' transform: translate3d(0, ' + distance[direction] + 'px, 0);' + + ' }' + ; + } + + /* IE is only browser not to create context with transforms */ + /* https://www.w3.org/Bugs/Public/show_bug.cgi?id=16328 */ + if( module.is.ie() ) { + if(direction === 'left' || direction === 'right') { + module.debug('Adding CSS rules for animation distance', width); + style += '' + + ' body.pushable > .ui.visible.' + direction + '.sidebar ~ .pusher:after {' + + ' -webkit-transform: translate3d('+ distance[direction] + 'px, 0, 0);' + + ' transform: translate3d('+ distance[direction] + 'px, 0, 0);' + + ' }' + ; + } + else if(direction === 'top' || direction == 'bottom') { + style += '' + + ' body.pushable > .ui.visible.' + direction + '.sidebar ~ .pusher:after {' + + ' -webkit-transform: translate3d(0, ' + distance[direction] + 'px, 0);' + + ' transform: translate3d(0, ' + distance[direction] + 'px, 0);' + + ' }' + ; + } + /* opposite sides visible forces content overlay */ + style += '' + + ' body.pushable > .ui.visible.left.sidebar ~ .ui.visible.right.sidebar ~ .pusher:after,' + + ' body.pushable > .ui.visible.right.sidebar ~ .ui.visible.left.sidebar ~ .pusher:after {' + + ' -webkit-transform: translate3d(0, 0, 0);' + + ' transform: translate3d(0, 0, 0);' + + ' }' + ; + } + style += '</style>'; + $style = $(style) + .appendTo($head) + ; + module.debug('Adding sizing css to head', $style); + } + }, + + refresh: function() { + module.verbose('Refreshing selector cache'); + $context = $(settings.context); + $sidebars = $context.children(selector.sidebar); + $pusher = $context.children(selector.pusher); + $fixed = $context.children(selector.fixed); + module.clear.cache(); + }, + + refreshSidebars: function() { + module.verbose('Refreshing other sidebars'); + $sidebars = $context.children(selector.sidebar); + }, + + repaint: function() { + module.verbose('Forcing repaint event'); + element.style.display = 'none'; + var ignored = element.offsetHeight; + element.scrollTop = element.scrollTop; + element.style.display = ''; + }, + + setup: { + cache: function() { + module.cache = { + width : $module.outerWidth(), + height : $module.outerHeight() + }; + }, + layout: function() { + if( $context.children(selector.pusher).length === 0 ) { + module.debug('Adding wrapper element for sidebar'); + module.error(error.pusher); + $pusher = $('<div class="pusher" />'); + $context + .children() + .not(selector.omitted) + .not($sidebars) + .wrapAll($pusher) + ; + module.refresh(); + } + if($module.nextAll(selector.pusher).length === 0 || $module.nextAll(selector.pusher)[0] !== $pusher[0]) { + module.debug('Moved sidebar to correct parent element'); + module.error(error.movedSidebar, element); + $module.detach().prependTo($context); + module.refresh(); + } + module.clear.cache(); + module.set.pushable(); + module.set.direction(); + } + }, + + attachEvents: function(selector, event) { + var + $toggle = $(selector) + ; + event = $.isFunction(module[event]) + ? module[event] + : module.toggle + ; + if($toggle.length > 0) { + module.debug('Attaching sidebar events to element', selector, event); + $toggle + .on('click' + eventNamespace, event) + ; + } + else { + module.error(error.notFound, selector); + } + }, + + show: function(callback) { + callback = $.isFunction(callback) + ? callback + : function(){} + ; + if(module.is.hidden()) { + module.refreshSidebars(); + if(settings.overlay) { + module.error(error.overlay); + settings.transition = 'overlay'; + } + module.refresh(); + if(module.othersActive()) { + module.debug('Other sidebars currently visible'); + if(settings.exclusive) { + // if not overlay queue animation after hide + if(settings.transition != 'overlay') { + module.hideOthers(module.show); + return; + } + else { + module.hideOthers(); + } + } + else { + settings.transition = 'overlay'; + } + } + module.pushPage(function() { + callback.call(element); + settings.onShow.call(element); + }); + settings.onChange.call(element); + settings.onVisible.call(element); + } + else { + module.debug('Sidebar is already visible'); + } + }, + + hide: function(callback) { + callback = $.isFunction(callback) + ? callback + : function(){} + ; + if(module.is.visible() || module.is.animating()) { + module.debug('Hiding sidebar', callback); + module.refreshSidebars(); + module.pullPage(function() { + callback.call(element); + settings.onHidden.call(element); + }); + settings.onChange.call(element); + settings.onHide.call(element); + } + }, + + othersAnimating: function() { + return ($sidebars.not($module).filter('.' + className.animating).length > 0); + }, + othersVisible: function() { + return ($sidebars.not($module).filter('.' + className.visible).length > 0); + }, + othersActive: function() { + return(module.othersVisible() || module.othersAnimating()); + }, + + hideOthers: function(callback) { + var + $otherSidebars = $sidebars.not($module).filter('.' + className.visible), + sidebarCount = $otherSidebars.length, + callbackCount = 0 + ; + callback = callback || function(){}; + $otherSidebars + .sidebar('hide', function() { + callbackCount++; + if(callbackCount == sidebarCount) { + callback(); + } + }) + ; + }, + + toggle: function() { + module.verbose('Determining toggled direction'); + if(module.is.hidden()) { + module.show(); + } + else { + module.hide(); + } + }, + + pushPage: function(callback) { + var + transition = module.get.transition(), + $transition = (transition === 'overlay' || module.othersActive()) + ? $module + : $pusher, + animate, + dim, + transitionEnd + ; + callback = $.isFunction(callback) + ? callback + : function(){} + ; + if(settings.transition == 'scale down') { + module.scrollToTop(); + } + module.set.transition(transition); + module.repaint(); + animate = function() { + module.bind.clickaway(); + module.add.inlineCSS(); + module.set.animating(); + module.set.visible(); + }; + dim = function() { + module.set.dimmed(); + }; + transitionEnd = function(event) { + if( event.target == $transition[0] ) { + $transition.off(transitionEvent + elementNamespace, transitionEnd); + module.remove.animating(); + module.bind.scrollLock(); + callback.call(element); + } + }; + $transition.off(transitionEvent + elementNamespace); + $transition.on(transitionEvent + elementNamespace, transitionEnd); + requestAnimationFrame(animate); + if(settings.dimPage && !module.othersVisible()) { + requestAnimationFrame(dim); + } + }, + + pullPage: function(callback) { + var + transition = module.get.transition(), + $transition = (transition == 'overlay' || module.othersActive()) + ? $module + : $pusher, + animate, + transitionEnd + ; + callback = $.isFunction(callback) + ? callback + : function(){} + ; + module.verbose('Removing context push state', module.get.direction()); + + module.unbind.clickaway(); + module.unbind.scrollLock(); + + animate = function() { + module.set.transition(transition); + module.set.animating(); + module.remove.visible(); + if(settings.dimPage && !module.othersVisible()) { + $pusher.removeClass(className.dimmed); + } + }; + transitionEnd = function(event) { + if( event.target == $transition[0] ) { + $transition.off(transitionEvent + elementNamespace, transitionEnd); + module.remove.animating(); + module.remove.transition(); + module.remove.inlineCSS(); + if(transition == 'scale down' || (settings.returnScroll && module.is.mobile()) ) { + module.scrollBack(); + } + callback.call(element); + } + }; + $transition.off(transitionEvent + elementNamespace); + $transition.on(transitionEvent + elementNamespace, transitionEnd); + requestAnimationFrame(animate); + }, + + scrollToTop: function() { + module.verbose('Scrolling to top of page to avoid animation issues'); + currentScroll = $(window).scrollTop(); + $module.scrollTop(0); + window.scrollTo(0, 0); + }, + + scrollBack: function() { + module.verbose('Scrolling back to original page position'); + window.scrollTo(0, currentScroll); + }, + + clear: { + cache: function() { + module.verbose('Clearing cached dimensions'); + module.cache = {}; + } + }, + + set: { + + // ios only (scroll on html not document). This prevent auto-resize canvas/scroll in ios + // (This is no longer necessary in latest iOS) + ios: function() { + $html.addClass(className.ios); + }, + + // container + pushed: function() { + $context.addClass(className.pushed); + }, + pushable: function() { + $context.addClass(className.pushable); + }, + + // pusher + dimmed: function() { + $pusher.addClass(className.dimmed); + }, + + // sidebar + active: function() { + $module.addClass(className.active); + }, + animating: function() { + $module.addClass(className.animating); + }, + transition: function(transition) { + transition = transition || module.get.transition(); + $module.addClass(transition); + }, + direction: function(direction) { + direction = direction || module.get.direction(); + $module.addClass(className[direction]); + }, + visible: function() { + $module.addClass(className.visible); + }, + overlay: function() { + $module.addClass(className.overlay); + } + }, + remove: { + + inlineCSS: function() { + module.debug('Removing inline css styles', $style); + if($style && $style.length > 0) { + $style.remove(); + } + }, + + // ios scroll on html not document + ios: function() { + $html.removeClass(className.ios); + }, + + // context + pushed: function() { + $context.removeClass(className.pushed); + }, + pushable: function() { + $context.removeClass(className.pushable); + }, + + // sidebar + active: function() { + $module.removeClass(className.active); + }, + animating: function() { + $module.removeClass(className.animating); + }, + transition: function(transition) { + transition = transition || module.get.transition(); + $module.removeClass(transition); + }, + direction: function(direction) { + direction = direction || module.get.direction(); + $module.removeClass(className[direction]); + }, + visible: function() { + $module.removeClass(className.visible); + }, + overlay: function() { + $module.removeClass(className.overlay); + } + }, + + get: { + direction: function() { + if($module.hasClass(className.top)) { + return className.top; + } + else if($module.hasClass(className.right)) { + return className.right; + } + else if($module.hasClass(className.bottom)) { + return className.bottom; + } + return className.left; + }, + transition: function() { + var + direction = module.get.direction(), + transition + ; + transition = ( module.is.mobile() ) + ? (settings.mobileTransition == 'auto') + ? settings.defaultTransition.mobile[direction] + : settings.mobileTransition + : (settings.transition == 'auto') + ? settings.defaultTransition.computer[direction] + : settings.transition + ; + module.verbose('Determined transition', transition); + return transition; + }, + transitionEvent: function() { + var + element = document.createElement('element'), + transitions = { + 'transition' :'transitionend', + 'OTransition' :'oTransitionEnd', + 'MozTransition' :'transitionend', + 'WebkitTransition' :'webkitTransitionEnd' + }, + transition + ; + for(transition in transitions){ + if( element.style[transition] !== undefined ){ + return transitions[transition]; + } + } + } + }, + + is: { + + ie: function() { + var + isIE11 = (!(window.ActiveXObject) && 'ActiveXObject' in window), + isIE = ('ActiveXObject' in window) + ; + return (isIE11 || isIE); + }, + + ios: function() { + var + userAgent = navigator.userAgent, + isIOS = userAgent.match(regExp.ios), + isMobileChrome = userAgent.match(regExp.mobileChrome) + ; + if(isIOS && !isMobileChrome) { + module.verbose('Browser was found to be iOS', userAgent); + return true; + } + else { + return false; + } + }, + mobile: function() { + var + userAgent = navigator.userAgent, + isMobile = userAgent.match(regExp.mobile) + ; + if(isMobile) { + module.verbose('Browser was found to be mobile', userAgent); + return true; + } + else { + module.verbose('Browser is not mobile, using regular transition', userAgent); + return false; + } + }, + hidden: function() { + return !module.is.visible(); + }, + visible: function() { + return $module.hasClass(className.visible); + }, + // alias + open: function() { + return module.is.visible(); + }, + closed: function() { + return module.is.hidden(); + }, + vertical: function() { + return $module.hasClass(className.top); + }, + animating: function() { + return $context.hasClass(className.animating); + }, + rtl: function () { + if(module.cache.rtl === undefined) { + module.cache.rtl = $module.attr('dir') === 'rtl' || $module.css('direction') === 'rtl'; + } + return module.cache.rtl; + } + }, + + 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(Array.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) { + module.invoke('destroy'); + } + module.initialize(); + } + }); + + return (returnedValue !== undefined) + ? returnedValue + : this + ; +}; + +$.fn.sidebar.settings = { + + name : 'Sidebar', + namespace : 'sidebar', + + silent : false, + debug : false, + verbose : false, + performance : true, + + transition : 'auto', + mobileTransition : 'auto', + + defaultTransition : { + computer: { + left : 'uncover', + right : 'uncover', + top : 'overlay', + bottom : 'overlay' + }, + mobile: { + left : 'uncover', + right : 'uncover', + top : 'overlay', + bottom : 'overlay' + } + }, + + context : 'body', + exclusive : false, + closable : true, + dimPage : true, + scrollLock : false, + returnScroll : false, + delaySetup : false, + + duration : 500, + + onChange : function(){}, + onShow : function(){}, + onHide : function(){}, + + onHidden : function(){}, + onVisible : function(){}, + + className : { + active : 'active', + animating : 'animating', + dimmed : 'dimmed', + ios : 'ios', + pushable : 'pushable', + pushed : 'pushed', + right : 'right', + top : 'top', + left : 'left', + bottom : 'bottom', + visible : 'visible' + }, + + selector: { + fixed : '.fixed', + omitted : 'script, link, style, .ui.modal, .ui.dimmer, .ui.nag, .ui.fixed', + pusher : '.pusher', + sidebar : '.ui.sidebar' + }, + + regExp: { + ios : /(iPad|iPhone|iPod)/g, + mobileChrome : /(CriOS)/g, + mobile : /Mobile|iP(hone|od|ad)|Android|BlackBerry|IEMobile|Kindle|NetFront|Silk-Accelerated|(hpw|web)OS|Fennec|Minimo|Opera M(obi|ini)|Blazer|Dolfin|Dolphin|Skyfire|Zune/g + }, + + error : { + method : 'The method you called is not defined.', + pusher : 'Had to add pusher element. For optimal performance make sure body content is inside a pusher element', + movedSidebar : 'Had to move sidebar. For optimal performance make sure sidebar and pusher are direct children of your body tag', + overlay : 'The overlay setting is no longer supported, use animation: overlay', + notFound : 'There were no elements that matched the specified selector' + } + +}; + + +})( jQuery, window, document ); diff --git a/semantic/src/definitions/modules/sidebar.less b/semantic/src/definitions/modules/sidebar.less new file mode 100644 index 0000000..54e1400 --- /dev/null +++ b/semantic/src/definitions/modules/sidebar.less @@ -0,0 +1,654 @@ +/*! + * # Fomantic-UI - Sidebar + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + + + +/******************************* + Theme +*******************************/ + +@type : 'module'; +@element : 'sidebar'; + +@import (multiple) '../../theme.config'; + +/******************************* + Sidebar +*******************************/ + +/* Sidebar Menu */ +.ui.sidebar { + position: fixed; + top: 0; + left: 0; + + backface-visibility: hidden; + transition: none; + will-change: transform; + transform: translate3d(0, 0, 0); + visibility: hidden; + -webkit-overflow-scrolling: touch; + + height: 100% !important; + max-height: 100%; + border-radius: 0 !important; + margin: 0 !important; + overflow-y: auto !important; + z-index: @topLayer; +} + +/* GPU Layers for Child Elements */ +.ui.sidebar > * { + backface-visibility: hidden; +} + + +/*-------------- + Direction +---------------*/ +& when (@variationSidebarLeft) { + .ui.left.sidebar { + right: auto; + left: 0; + transform: translate3d(-100%, 0, 0); + } +} +& when (@variationSidebarRight) { + .ui.right.sidebar { + right: 0 !important; + left: auto !important; + transform: translate3d(100%, 0, 0); + } +} + +& when (@variationSidebarTop) or (@variationSidebarBottom) { + .ui.top.sidebar, + .ui.bottom.sidebar { + width: 100% !important; + height: auto !important; + } + & when (@variationSidebarTop) { + .ui.top.sidebar { + top: 0 !important; + bottom: auto !important; + transform: translate3d(0, -100%, 0); + } + } + & when (@variationSidebarBottom) { + .ui.bottom.sidebar { + top: auto !important; + bottom: 0 !important; + transform: translate3d(0, 100%, 0); + } + } +} + + +/*-------------- + Pushable +---------------*/ + +.pushable { + height: 100%; + overflow-x: hidden; + padding: 0 !important; +} + +/* Whole Page */ +body.pushable { + background: @canvasBackground; + &.dimmed { + background: inherit; + } +} + +/* Page Context */ +.pushable:not(body) { + transform: translate3d(0, 0, 0); + overflow-y: hidden; +} +.pushable:not(body) > .ui.sidebar, +.pushable:not(body) > .fixed, +.pushable:not(body) > .pusher:after { + position: absolute; +} + + +/*-------------- + Fixed +---------------*/ + +.pushable > .fixed { + position: fixed; + backface-visibility: hidden; + + transition: transform @duration @easing; + will-change: transform; + z-index: @fixedLayer; +} + +/*-------------- + Page +---------------*/ + +.pushable > .pusher { + position: relative; + backface-visibility: hidden; + overflow: hidden; + min-height: 100%; + transition: transform @duration @easing; + z-index: @middleLayer; + + /* Pusher should inherit background from context */ + background: inherit; +} + +body.pushable > .pusher { + background: @pageBackground; +} + +/*-------------- + Dimmer +---------------*/ + +.pushable > .pusher:after { + position: fixed; + top: 0; + right: 0; + content: ''; + background: @dimmerColor; + overflow: hidden; + opacity: 0; + transition: @dimmerTransition; + will-change: opacity; + z-index: @dimmerLayer; +} + +/*-------------- + Coupling +---------------*/ + +.ui.sidebar.menu .item { + border-radius: 0 !important; +} + +/******************************* + States +*******************************/ + +/*-------------- + Dimmed +---------------*/ + +.pushable > .pusher.dimmed:after { + width: 100% !important; + height: 100% !important; + opacity: 1 !important; +} + +/*-------------- + Animating +---------------*/ + +.ui.animating.sidebar { + visibility: visible; +} + +/*-------------- + Visible +---------------*/ + +.ui.visible.sidebar { + visibility: visible; + transform: translate3d(0, 0, 0); +} + +/* Shadow Direction */ +& when (@variationSidebarLeft) or (@variationSidebarRight) { + .ui.left.visible.sidebar, + .ui.right.visible.sidebar { + box-shadow: @horizontalBoxShadow; + } +} +& when (@variationSidebarTop) or (@variationSidebarBottom) { + .ui.top.visible.sidebar, + .ui.bottom.visible.sidebar { + box-shadow: @verticalBoxShadow; + } +} + +/* Visible On Load */ +& when (@variationSidebarLeft) { + .ui.visible.left.sidebar ~ .fixed, + .ui.visible.left.sidebar ~ .pusher { + transform: translate3d(@width, 0, 0); + } +} +& when (@variationSidebarRight) { + .ui.visible.right.sidebar ~ .fixed, + .ui.visible.right.sidebar ~ .pusher { + transform: translate3d(-@width, 0, 0); + } +} +& when (@variationSidebarTop) { + .ui.visible.top.sidebar ~ .fixed, + .ui.visible.top.sidebar ~ .pusher { + transform: translate3d(0, @height, 0); + } +} +& when (@variationSidebarBottom) { + .ui.visible.bottom.sidebar ~ .fixed, + .ui.visible.bottom.sidebar ~ .pusher { + transform: translate3d(0, -@height, 0); + } +} + +& when (@variationSidebarLeft) or (@variationSidebarRight) { + /* opposite sides visible forces content overlay */ + .ui.visible.left.sidebar ~ .ui.visible.right.sidebar ~ .fixed, + .ui.visible.left.sidebar ~ .ui.visible.right.sidebar ~ .pusher, + .ui.visible.right.sidebar ~ .ui.visible.left.sidebar ~ .fixed, + .ui.visible.right.sidebar ~ .ui.visible.left.sidebar ~ .pusher { + transform: translate3d(0, 0, 0); + } +} + +/*-------------- + iOS +---------------*/ + + +/******************************* + Variations +*******************************/ + +/*-------------- + Width +---------------*/ + +/* Left / Right */ +& when (@variationSidebarLeft) or (@variationSidebarRight) { + & when (@variationSidebarThin) { + .ui.thin.left.sidebar, + .ui.thin.right.sidebar { + width: @thinWidth; + } + + .ui[class*="very thin"].left.sidebar, + .ui[class*="very thin"].right.sidebar { + width: @veryThinWidth; + } + } + + .ui.left.sidebar, + .ui.right.sidebar { + width: @width; + } + + & when (@variationSidebarWide) { + .ui.wide.left.sidebar, + .ui.wide.right.sidebar { + width: @wideWidth; + } + + .ui[class*="very wide"].left.sidebar, + .ui[class*="very wide"].right.sidebar { + width: @veryWideWidth; + } + } + + /* Left Visible */ + & when (@variationSidebarLeft) { + & when (@variationSidebarThin) { + .ui.visible.thin.left.sidebar ~ .fixed, + .ui.visible.thin.left.sidebar ~ .pusher { + transform: translate3d(@thinWidth, 0, 0); + } + + .ui.visible[class*="very thin"].left.sidebar ~ .fixed, + .ui.visible[class*="very thin"].left.sidebar ~ .pusher { + transform: translate3d(@veryThinWidth, 0, 0); + } + } + + & when (@variationSidebarWide) { + .ui.visible.wide.left.sidebar ~ .fixed, + .ui.visible.wide.left.sidebar ~ .pusher { + transform: translate3d(@wideWidth, 0, 0); + } + + .ui.visible[class*="very wide"].left.sidebar ~ .fixed, + .ui.visible[class*="very wide"].left.sidebar ~ .pusher { + transform: translate3d(@veryWideWidth, 0, 0); + } + } + } + + /* Right Visible */ + & when (@variationSidebarRight) { + & when (@variationSidebarThin) { + .ui.visible.thin.right.sidebar ~ .fixed, + .ui.visible.thin.right.sidebar ~ .pusher { + transform: translate3d(-@thinWidth, 0, 0); + } + + .ui.visible[class*="very thin"].right.sidebar ~ .fixed, + .ui.visible[class*="very thin"].right.sidebar ~ .pusher { + transform: translate3d(-@veryThinWidth, 0, 0); + } + } + + & when (@variationSidebarWide) { + .ui.visible.wide.right.sidebar ~ .fixed, + .ui.visible.wide.right.sidebar ~ .pusher { + transform: translate3d(-@wideWidth, 0, 0); + } + + .ui.visible[class*="very wide"].right.sidebar ~ .fixed, + .ui.visible[class*="very wide"].right.sidebar ~ .pusher { + transform: translate3d(-@veryWideWidth, 0, 0); + } + } + } +} + + + +/******************************* + Animations +*******************************/ + +& when (@variationSidebarOverlay) { + /*-------------- + Overlay + ---------------*/ + + /* Set-up */ + .ui.overlay.sidebar { + z-index: @topLayer; + } + + /* Initial */ + & when (@variationSidebarLeft) { + .ui.left.overlay.sidebar { + transform: translate3d(-100%, 0, 0); + } + } + & when (@variationSidebarRight) { + .ui.right.overlay.sidebar { + transform: translate3d(100%, 0, 0); + } + } + & when (@variationSidebarTop) { + .ui.top.overlay.sidebar { + transform: translate3d(0%, -100%, 0); + } + } + & when (@variationSidebarBottom) { + .ui.bottom.overlay.sidebar { + transform: translate3d(0%, 100%, 0); + } + } + + /* Animation */ + .animating.ui.overlay.sidebar, + .ui.visible.overlay.sidebar { + transition: transform @duration @easing; + } + + /* End - Sidebar */ + & when (@variationSidebarLeft) { + .ui.visible.left.overlay.sidebar { + transform: translate3d(0%, 0, 0); + } + } + & when (@variationSidebarRight) { + .ui.visible.right.overlay.sidebar { + transform: translate3d(0%, 0, 0); + } + } + & when (@variationSidebarTop) { + .ui.visible.top.overlay.sidebar { + transform: translate3d(0%, 0, 0); + } + } + & when (@variationSidebarBottom) { + .ui.visible.bottom.overlay.sidebar { + transform: translate3d(0%, 0, 0); + } + } + /* End - Pusher */ + .ui.visible.overlay.sidebar ~ .fixed, + .ui.visible.overlay.sidebar ~ .pusher { + transform: none !important; + } +} + + +& when (@variationSidebarPush) { + /*-------------- + Push + ---------------*/ + + /* Initial */ + .ui.push.sidebar { + transition: transform @duration @easing; + z-index: @topLayer; + } + + /* Sidebar - Initial */ + & when (@variationSidebarLeft) { + .ui.left.push.sidebar { + transform: translate3d(-100%, 0, 0); + } + } + & when (@variationSidebarRight) { + .ui.right.push.sidebar { + transform: translate3d(100%, 0, 0); + } + } + & when (@variationSidebarTop) { + .ui.top.push.sidebar { + transform: translate3d(0%, -100%, 0); + } + } + & when (@variationSidebarBottom) { + .ui.bottom.push.sidebar { + transform: translate3d(0%, 100%, 0); + } + } + + /* End */ + .ui.visible.push.sidebar { + transform: translate3d(0%, 0, 0); + } +} + +& when (@variationSidebarUncover) { + /*-------------- + Uncover + ---------------*/ + + /* Initial */ + .ui.uncover.sidebar { + transform: translate3d(0, 0, 0); + z-index: @bottomLayer; + } + + /* End */ + .ui.visible.uncover.sidebar { + transform: translate3d(0, 0, 0); + transition: transform @duration @easing; + } +} + +& when (@variationSidebarSlideAlong) { + /*-------------- + Slide Along + ---------------*/ + + /* Initial */ + .ui.slide.along.sidebar { + z-index: @bottomLayer; + } + + /* Sidebar - Initial */ + & when (@variationSidebarLeft) { + .ui.left.slide.along.sidebar { + transform: translate3d(-50%, 0, 0); + } + } + & when (@variationSidebarRight) { + .ui.right.slide.along.sidebar { + transform: translate3d(50%, 0, 0); + } + } + & when (@variationSidebarTop) { + .ui.top.slide.along.sidebar { + transform: translate3d(0, -50%, 0); + } + } + & when (@variationSidebarBottom) { + .ui.bottom.slide.along.sidebar { + transform: translate3d(0%, 50%, 0); + } + } + + /* Animation */ + .ui.animating.slide.along.sidebar { + transition: transform @duration @easing; + } + + /* End */ + .ui.visible.slide.along.sidebar { + transform: translate3d(0%, 0, 0); + } +} + +& when (@variationSidebarSlideOut) { + /*-------------- + Slide Out + ---------------*/ + + /* Initial */ + .ui.slide.out.sidebar { + z-index: @bottomLayer; + } + + /* Sidebar - Initial */ + & when (@variationSidebarLeft) { + .ui.left.slide.out.sidebar { + transform: translate3d(50%, 0, 0); + } + } + & when (@variationSidebarRight) { + .ui.right.slide.out.sidebar { + transform: translate3d(-50%, 0, 0); + } + } + & when (@variationSidebarTop) { + .ui.top.slide.out.sidebar { + transform: translate3d(0%, 50%, 0); + } + } + & when (@variationSidebarBottom) { + .ui.bottom.slide.out.sidebar { + transform: translate3d(0%, -50%, 0); + } + } + + /* Animation */ + .ui.animating.slide.out.sidebar { + transition: transform @duration @easing; + } + + /* End */ + .ui.visible.slide.out.sidebar { + transform: translate3d(0%, 0, 0); + } +} + +& when (@variationSidebarScale) { + /*-------------- + Scale Down + ---------------*/ + + /* Initial */ + .ui.scale.down.sidebar { + transition: transform @duration @easing; + z-index: @topLayer; + } + + + & when (@variationSidebarLeft) { + .ui.left.scale.down.sidebar { + transform: translate3d(-100%, 0, 0); + } + } + & when (@variationSidebarRight) { + .ui.right.scale.down.sidebar { + transform: translate3d(100%, 0, 0); + } + } + & when (@variationSidebarTop) { + .ui.top.scale.down.sidebar { + transform: translate3d(0%, -100%, 0); + } + } + & when (@variationSidebarBottom) { + .ui.bottom.scale.down.sidebar { + transform: translate3d(0%, 100%, 0); + } + } + + /* Pusher - Initial */ + & when (@variationSidebarLeft) { + .ui.scale.down.left.sidebar ~ .pusher { + transform-origin: 75% 50%; + } + } + & when (@variationSidebarRight) { + .ui.scale.down.right.sidebar ~ .pusher { + transform-origin: 25% 50%; + } + } + & when (@variationSidebarTop) { + .ui.scale.down.top.sidebar ~ .pusher { + transform-origin: 50% 75%; + } + } + & when (@variationSidebarBottom) { + .ui.scale.down.bottom.sidebar ~ .pusher { + transform-origin: 50% 25%; + } + } + + /* Animation */ + .ui.animating.scale.down > .visible.ui.sidebar { + transition: transform @duration @easing; + } + .ui.visible.scale.down.sidebar ~ .pusher, + .ui.animating.scale.down.sidebar ~ .pusher { + display: block !important; + width: 100%; + height: 100%; + overflow: hidden !important; + } + + /* End */ + .ui.visible.scale.down.sidebar { + transform: translate3d(0, 0, 0); + } + .ui.visible.scale.down.sidebar ~ .pusher { + transform: scale(0.75); + } +} + +.loadUIOverrides(); diff --git a/semantic/src/definitions/modules/slider.js b/semantic/src/definitions/modules/slider.js new file mode 100644 index 0000000..11d8ca3 --- /dev/null +++ b/semantic/src/definitions/modules/slider.js @@ -0,0 +1,1314 @@ +/*! + * # Fomantic-UI - Slider + * http://github.com/fomantic/Fomantic-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), + $window = $(window), + + 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, + gapRatio = 1, + + initialPosition, + initialLoad, + module + ; + + module = { + + initialize: function() { + module.debug('Initializing slider', settings); + initialLoad = true; + + 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(); + + initialLoad = false; + 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("<div class='inner'>" + + "<div class='track'></div>" + + "<div class='track-fill'></div>" + + "<div class='thumb'></div>" + + "</div>"); + } + 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("<div class='thumb second'></div>"); + } + $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('<ul class="auto labels"></ul>').find('.labels'); + } + for(var i = 0, len = module.get.numLabels(); i <= len; i++) { + var + labelText = module.get.label(i), + $label = (labelText !== "") + ? !(i % module.get.gapRatio()) + ? $('<li class="label">' + labelText + '</li>') + : $('<li class="halftick label"></li>') + : 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(); + } + if (settings.autoAdjustLabels) { + module.bind.windowEvents(); + } + }, + 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); + } + }, + windowEvents: function() { + $window.on('resize' + eventNamespace, module.event.resize); + } + }, + + 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); + $window.off('resize' + eventNamespace); + }, + 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) { + event.preventDefault(); + if(module.is.range()) { + var + eventPos = module.determine.eventPos(event), + newPos = module.determine.pos(eventPos) + ; + // Special handling if range mode and both thumbs have the same value + if(settings.preventCrossover && module.is.range() && module.thumbVal === module.secondThumbVal) { + initialPosition = newPos; + $currThumb = undefined; + } else { + $currThumb = module.determine.closestThumb(newPos); + } + } + if(!module.is.disabled()) { + module.bind.slidingEvents(); + } + }, + move: function(event) { + event.preventDefault(); + var value = module.determine.valueFromEvent(event); + if($currThumb === undefined) { + var + eventPos = module.determine.eventPos(event), + newPos = module.determine.pos(eventPos) + ; + $currThumb = initialPosition > newPos ? $thumb : $secondThumb; + } + if(module.get.step() == 0 || module.is.smooth()) { + var + thumbVal = module.thumbVal, + secondThumbVal = module.secondThumbVal, + thumbSmoothVal = module.determine.smoothValueFromEvent(event) + ; + if(!$currThumb.hasClass('second')) { + if(settings.preventCrossover && module.is.range()) { + value = Math.min(secondThumbVal, value); + thumbSmoothVal = Math.min(secondThumbVal, thumbSmoothVal); + } + thumbVal = value; + } else { + if(settings.preventCrossover && module.is.range()) { + value = Math.max(thumbVal, value); + thumbSmoothVal = Math.max(thumbVal, thumbSmoothVal); + } + 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) { + event.preventDefault(); + var value = module.determine.valueFromEvent(event); + module.set.value(value); + module.unbind.slidingEvents(); + }, + keydown: function(event, first) { + if(settings.preventCrossover && module.is.range() && module.thumbVal === module.secondThumbVal) { + $currThumb = undefined; + } + 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(); + } + }, + resize: function(_event) { + // To avoid a useless performance cost, we only call the label refresh when its necessary + if (gapRatio != module.get.gapRatio()) { + module.setup.labels(); + gapRatio = module.get.gapRatio(); + } + } + }, + + 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() { + var step = module.get.step(), + min = module.get.min(), + quotient = step === 0 ? 0 : Math.floor((settings.max - min) / step), + remainder = step === 0 ? 0 : (settings.max - min) % step; + return remainder === 0 ? settings.max : min + quotient * step; + }, + step: function() { + return settings.step; + }, + numLabels: function() { + var value = Math.round((module.get.max() - module.get.min()) / module.get.step()); + module.debug('Determined that there 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 Math.round(((value * module.get.step()) + module.get.min()) * precision ) / precision; + case settings.labelTypes.letter: + return alphabet[(value) % 26]; + default: + return value; + } + }, + value: function() { + return value; + }, + currentThumbValue: function() { + return $currThumb !== undefined && $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; + } + }, + gapRatio: function() { + var gapRatio = 1; + + if( settings.autoAdjustLabels ) { + var + numLabels = module.get.numLabels(), + trackLength = module.get.trackLength(), + gapCounter = 1 + ; + + // While the distance between two labels is too short, + // we divide the number of labels at each iteration + // and apply only if the modulo of the operation is an odd number. + if(trackLength>0){ + while ((trackLength / numLabels) * gapCounter < settings.labelDistance) { + if( !(numLabels % gapCounter) ) { + gapRatio = gapCounter; + } + gapCounter += 1; + } + } + } + return gapRatio; + } + }, + + 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) + ; + if(thumbDelta === secondThumbDelta && module.get.thumbValue() === module.get.min()) { + return $secondThumb; + } + 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) { + var + eventPos = module.determine.eventPos(event), + 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) { + var + min = module.get.min(), + max = module.get.max(), + trackLength = module.get.trackLength(), + eventPos = module.determine.eventPos(event), + 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) { + if(module.is.touch()) { + var + touchEvent = event.changedTouches ? event : event.originalEvent, + touches = touchEvent.changedTouches[0] ? touchEvent.changedTouches : touchEvent.touches, + touchY = touches[0].pageY, + touchX = touches[0].pageX + ; + return module.is.vertical() ? touchY : touchX; + } + var + clickY = event.pageY || event.originalEvent.pageY, + clickX = event.pageX || event.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) + module.verbose('Cutting off additional decimal places'); + return Math.round((difference + module.get.min()) * precision) / precision; + }, + 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) { + if (!initialLoad || settings.fireOnInit){ + 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); + if (!initialLoad || settings.fireOnInit) { + 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 === undefined) { + $currThumb = newValue <= module.get.currentThumbValue() ? $thumb : $secondThumb; + } + if(!$currThumb.hasClass('second')) { + if(settings.preventCrossover && module.is.range()) { + newValue = Math.min(module.secondThumbVal, newValue); + } + module.thumbVal = newValue; + } else { + if(settings.preventCrossover && module.is.range()) { + newValue = Math.max(module.thumbVal, newValue); + } + 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, + autoAdjustLabels : true, + labelDistance : 100, + preventCrossover : true, + fireOnInit : false, + interpretLabel : 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/semantic/src/definitions/modules/slider.less b/semantic/src/definitions/modules/slider.less new file mode 100644 index 0000000..7862859 --- /dev/null +++ b/semantic/src/definitions/modules/slider.less @@ -0,0 +1,417 @@ + /******************************* + Theme + *******************************/ + +@type : 'module'; +@element : 'slider'; + +@import (multiple) '../../theme.config'; + +.ui.slider:not(.vertical):not(.checkbox) { + width: 100%; + padding: @padding; +} + +.ui.slider:not(.checkbox) { + position: relative; +} + +.ui.slider:not(.checkbox):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 +*******************************/ + +& when (@variationSliderDisabled) { + /*-------------- + Disabled + ---------------*/ + + .ui.disabled.slider:not(.checkbox) { + opacity: @disabledOpactiy; + } + + .ui.disabled.slider .inner:hover { + cursor: auto; + } + + .ui.disabled.slider .inner .track-fill { + background: @disabledTrackFillColor; + } +} + +& when (@variationSliderReversed) { + /*-------------- + Reversed + ---------------*/ + + .ui.reversed.slider .inner .track-fill { + left: auto; + right: 0; + } + + .ui.reversed.slider:not(.vertical) .inner .thumb { + left: auto; + right: 0; + } + + .ui.reversed.vertical.slider .inner .thumb { + left: @thumbVerticalSliderOffset; + } + + & when (@variationSliderLabeled) { + .ui.labeled.reversed.slider > .labels .label { + transform: translate(-100%, -100%); + } + } +} + +/******************************* + Variations +*******************************/ + +& when (@variationSliderVertical) { + /*-------------- + 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; + } + & when (@variationSliderReversed) { + /* Vertical Reversed */ + .ui.vertical.reversed.slider .inner .thumb { + top: auto; + bottom: 0; + } + + .ui.vertical.reversed.slider .inner .track-fill { + top: auto; + bottom: 0; + } + } +} + +& when (@variationSliderLabeled) { + /*-------------- + 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; + padding: @labelPadding; + position: absolute; + transform: translate(-50%, -100%); + white-space: nowrap; + } + + .ui.bottom.aligned.labeled.slider > .labels .label { + transform: translate(-50%, 100%); + } + & when (@variationSliderTicked) { + .ui.labeled.ticked.slider > .labels .label:after { + content: ' '; + height: @labelHeight; + width: @labelWidth; + background: @labelColor; + position: absolute; + top: 100%; + left: 50%; + } + .ui.bottom.aligned.labeled.ticked.slider > .labels .label:after { + top: -100%; + } + .ui.labeled.ticked.slider > .labels .halftick.label:after { + height: @labelHeight / 2; + } + } + + & when (@variationSliderVertical) { + /* 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%; + } + .ui.labeled.vertical.slider > .labels .halftick.label:after { + width: @labelHeight / 2; + height: @labelWidth; + } + + & when (@variationSliderReversed) { + /* 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; +} + + +& when (@variationSliderInverted) { + /*-------------- + Inverted + ---------------*/ + + .ui.inverted.slider .inner .track-fill { + background-color: @invertedTrackFillColor; + } + + .ui.inverted.slider .inner .track { + background-color: @transparentWhite; + } +} + +/*-------------- + Colors +---------------*/ + +each(@colors, { + @color: replace(@key, '@', ''); + @c: @colors[@@color][color]; + @l: @colors[@@color][light]; + @h: @colors[@@color][hover]; + @lh: @colors[@@color][lightHover]; + + /* Standard */ + .ui.@{color}.slider .inner .track-fill { + background-color: @c; + } + & when (@variationSliderInverted) { + .ui.@{color}.inverted.slider .inner .track-fill { + background-color: @l; + } + } + + & when (@variationSliderBasic) { + /* Basic */ + .ui.@{color}.slider.basic .inner .thumb { + background-color: @c; + } + .ui.@{color}.slider.basic .inner .thumb:hover, + .ui.@{color}.slider.basic:focus .inner .thumb { + background-color: @h; + } + & when (@variationSliderInverted) { + /* Basic Inverted */ + .ui.@{color}.inverted.slider.basic .inner .thumb { + background-color: @l; + } + .ui.@{color}.inverted.slider.basic .inner .thumb:hover, + .ui.@{color}.inverted.slider.basic:focus .inner .thumb { + background-color: @lh; + } + } + } + +}) + +& when (@variationSliderBasic) { + /*-------------- + 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; + } + + & when (@variationSliderInverted) { + /*-------------- + 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 +---------------*/ + +& when not (@variationSliderSizes = false) { + each(@variationSliderSizes, { + @h: @{value}Height; + @th: @{value}TrackHeight; + @tp: @{value}TrackPositionTop; + @lh: @{value}LabelHeight; + .ui.slider.@{value} .inner .thumb { + height: @@h; + width: @@h; + } + .ui.slider.@{value}:not(.vertical) .inner { + height: @@h; + } + .ui.slider.@{value}:not(.vertical) .inner .track, + .ui.slider.@{value}:not(.vertical) .inner .track-fill { + height: @@th; + top: @@tp; + } + & when (@variationSliderLabeled) { + .ui.@{value}.labeled.slider:not(.vertical) > .labels, + .ui.@{value}.labeled.slider:not(.vertical) > .labels .label:after { + height: @@lh; + } + .ui.@{value}.labeled.slider:not(.vertical) > .labels .halftick.label:after { + height: @@lh / 2; + } + } + & when (@variationSliderVertical) { + /* Small Vertical */ + .ui.slider.@{value}.vertical .inner { + width: @@h; + } + .ui.slider.@{value}.vertical .inner .track, + .ui.slider.@{value}.vertical .inner .track-fill { + width: @@th; + left: @@tp; + } + & when (@variationSliderLabeled) { + .ui.@{value}.labeled.vertical.slider> .labels, + .ui.@{value}.labeled.vertical.slider> .labels .label:after { + width: @@lh; + } + .ui.@{value}.labeled.vertical.slider> .labels .halftick.label:after { + width: @@lh / 2; + } + } + } + }) +} + + +.loadUIOverrides(); diff --git a/semantic/src/definitions/modules/sticky.js b/semantic/src/definitions/modules/sticky.js new file mode 100644 index 0000000..561213f --- /dev/null +++ b/semantic/src/definitions/modules/sticky.js @@ -0,0 +1,957 @@ +/*! + * # Fomantic-UI - Sticky + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +'use strict'; + +$.isFunction = $.isFunction || function(obj) { + return typeof obj === "function" && typeof obj.nodeType !== "number"; +}; + +window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.fn.sticky = 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), + returnedValue + ; + + $allModules + .each(function() { + var + settings = ( $.isPlainObject(parameters) ) + ? $.extend(true, {}, $.fn.sticky.settings, parameters) + : $.extend({}, $.fn.sticky.settings), + + className = settings.className, + namespace = settings.namespace, + error = settings.error, + + eventNamespace = '.' + namespace, + moduleNamespace = 'module-' + namespace, + + $module = $(this), + $window = $(window), + $scroll = $(settings.scrollContext), + $container, + $context, + + instance = $module.data(moduleNamespace), + + requestAnimationFrame = window.requestAnimationFrame + || window.mozRequestAnimationFrame + || window.webkitRequestAnimationFrame + || window.msRequestAnimationFrame + || function(callback) { setTimeout(callback, 0); }, + + element = this, + + documentObserver, + observer, + module + ; + + module = { + + initialize: function() { + + module.determineContainer(); + module.determineContext(); + module.verbose('Initializing sticky', settings, $container); + + module.save.positions(); + module.checkErrors(); + module.bind.events(); + + if(settings.observeChanges) { + module.observeChanges(); + } + module.instantiate(); + }, + + instantiate: function() { + module.verbose('Storing instance of module', module); + instance = module; + $module + .data(moduleNamespace, module) + ; + }, + + destroy: function() { + module.verbose('Destroying previous instance'); + module.reset(); + if(documentObserver) { + documentObserver.disconnect(); + } + if(observer) { + observer.disconnect(); + } + $window + .off('load' + eventNamespace, module.event.load) + .off('resize' + eventNamespace, module.event.resize) + ; + $scroll + .off('scrollchange' + eventNamespace, module.event.scrollchange) + ; + $module.removeData(moduleNamespace); + }, + + observeChanges: function() { + if('MutationObserver' in window) { + documentObserver = new MutationObserver(module.event.documentChanged); + observer = new MutationObserver(module.event.changed); + documentObserver.observe(document, { + childList : true, + subtree : true + }); + observer.observe(element, { + childList : true, + subtree : true + }); + observer.observe($context[0], { + childList : true, + subtree : true + }); + module.debug('Setting up mutation observer', observer); + } + }, + + determineContainer: function() { + if(settings.container) { + $container = $(settings.container); + } + else { + $container = $module.offsetParent(); + } + }, + + determineContext: function() { + if(settings.context) { + $context = $(settings.context); + } + else { + $context = $container; + } + if($context.length === 0) { + module.error(error.invalidContext, settings.context, $module); + return; + } + }, + + checkErrors: function() { + if( module.is.hidden() ) { + module.error(error.visible, $module); + } + if(module.cache.element.height > module.cache.context.height) { + module.reset(); + module.error(error.elementSize, $module); + return; + } + }, + + bind: { + events: function() { + $window + .on('load' + eventNamespace, module.event.load) + .on('resize' + eventNamespace, module.event.resize) + ; + // pub/sub pattern + $scroll + .off('scroll' + eventNamespace) + .on('scroll' + eventNamespace, module.event.scroll) + .on('scrollchange' + eventNamespace, module.event.scrollchange) + ; + } + }, + + event: { + changed: function(mutations) { + clearTimeout(module.timer); + module.timer = setTimeout(function() { + module.verbose('DOM tree modified, updating sticky menu', mutations); + module.refresh(); + }, 100); + }, + documentChanged: function(mutations) { + [].forEach.call(mutations, function(mutation) { + if(mutation.removedNodes) { + [].forEach.call(mutation.removedNodes, function(node) { + if(node == element || $(node).find(element).length > 0) { + module.debug('Element removed from DOM, tearing down events'); + module.destroy(); + } + }); + } + }); + }, + load: function() { + module.verbose('Page contents finished loading'); + requestAnimationFrame(module.refresh); + }, + resize: function() { + module.verbose('Window resized'); + requestAnimationFrame(module.refresh); + }, + scroll: function() { + requestAnimationFrame(function() { + $scroll.triggerHandler('scrollchange' + eventNamespace, $scroll.scrollTop() ); + }); + }, + scrollchange: function(event, scrollPosition) { + module.stick(scrollPosition); + settings.onScroll.call(element); + } + }, + + refresh: function(hardRefresh) { + module.reset(); + if(!settings.context) { + module.determineContext(); + } + if(hardRefresh) { + module.determineContainer(); + } + module.save.positions(); + module.stick(); + settings.onReposition.call(element); + }, + + supports: { + sticky: function() { + var + $element = $('<div/>') + ; + $element.addClass(className.supported); + return($element.css('position').match('sticky')); + } + }, + + save: { + lastScroll: function(scroll) { + module.lastScroll = scroll; + }, + elementScroll: function(scroll) { + module.elementScroll = scroll; + }, + positions: function() { + var + scrollContext = { + height : $scroll.height() + }, + element = { + margin: { + top : parseInt($module.css('margin-top'), 10), + bottom : parseInt($module.css('margin-bottom'), 10), + }, + offset : $module.offset(), + width : $module.outerWidth(), + height : $module.outerHeight() + }, + context = { + offset : $context.offset(), + height : $context.outerHeight() + } + ; + if( !module.is.standardScroll() ) { + module.debug('Non-standard scroll. Removing scroll offset from element offset'); + + scrollContext.top = $scroll.scrollTop(); + scrollContext.left = $scroll.scrollLeft(); + + element.offset.top += scrollContext.top; + context.offset.top += scrollContext.top; + element.offset.left += scrollContext.left; + context.offset.left += scrollContext.left; + } + module.cache = { + fits : ( (element.height + settings.offset) <= scrollContext.height), + sameHeight : (element.height == context.height), + scrollContext : { + height : scrollContext.height + }, + element: { + margin : element.margin, + top : element.offset.top - element.margin.top, + left : element.offset.left, + width : element.width, + height : element.height, + bottom : element.offset.top + element.height + }, + context: { + top : context.offset.top, + height : context.height, + bottom : context.offset.top + context.height + } + }; + module.set.containerSize(); + + module.stick(); + module.debug('Caching element positions', module.cache); + } + }, + + get: { + direction: function(scroll) { + var + direction = 'down' + ; + scroll = scroll || $scroll.scrollTop(); + if(module.lastScroll !== undefined) { + if(module.lastScroll < scroll) { + direction = 'down'; + } + else if(module.lastScroll > scroll) { + direction = 'up'; + } + } + return direction; + }, + scrollChange: function(scroll) { + scroll = scroll || $scroll.scrollTop(); + return (module.lastScroll) + ? (scroll - module.lastScroll) + : 0 + ; + }, + currentElementScroll: function() { + if(module.elementScroll) { + return module.elementScroll; + } + return ( module.is.top() ) + ? Math.abs(parseInt($module.css('top'), 10)) || 0 + : Math.abs(parseInt($module.css('bottom'), 10)) || 0 + ; + }, + + elementScroll: function(scroll) { + scroll = scroll || $scroll.scrollTop(); + var + element = module.cache.element, + scrollContext = module.cache.scrollContext, + delta = module.get.scrollChange(scroll), + maxScroll = (element.height - scrollContext.height + settings.offset), + elementScroll = module.get.currentElementScroll(), + possibleScroll = (elementScroll + delta) + ; + if(module.cache.fits || possibleScroll < 0) { + elementScroll = 0; + } + else if(possibleScroll > maxScroll ) { + elementScroll = maxScroll; + } + else { + elementScroll = possibleScroll; + } + return elementScroll; + } + }, + + remove: { + lastScroll: function() { + delete module.lastScroll; + }, + elementScroll: function(scroll) { + delete module.elementScroll; + }, + minimumSize: function() { + $container + .css('min-height', '') + ; + }, + offset: function() { + $module.css('margin-top', ''); + } + }, + + set: { + offset: function() { + module.verbose('Setting offset on element', settings.offset); + $module + .css('margin-top', settings.offset) + ; + }, + containerSize: function() { + var + tagName = $container.get(0).tagName + ; + if(tagName === 'HTML' || tagName == 'body') { + // this can trigger for too many reasons + //module.error(error.container, tagName, $module); + module.determineContainer(); + } + else { + if( Math.abs($container.outerHeight() - module.cache.context.height) > settings.jitter) { + module.debug('Context has padding, specifying exact height for container', module.cache.context.height); + $container.css({ + height: module.cache.context.height + }); + } + } + }, + minimumSize: function() { + var + element = module.cache.element + ; + $container + .css('min-height', element.height) + ; + }, + scroll: function(scroll) { + module.debug('Setting scroll on element', scroll); + if(module.elementScroll == scroll) { + return; + } + if( module.is.top() ) { + $module + .css('bottom', '') + .css('top', -scroll) + ; + } + if( module.is.bottom() ) { + $module + .css('top', '') + .css('bottom', scroll) + ; + } + }, + size: function() { + if(module.cache.element.height !== 0 && module.cache.element.width !== 0) { + element.style.setProperty('width', module.cache.element.width + 'px', 'important'); + element.style.setProperty('height', module.cache.element.height + 'px', 'important'); + } + } + }, + + is: { + standardScroll: function() { + return ($scroll[0] == window); + }, + top: function() { + return $module.hasClass(className.top); + }, + bottom: function() { + return $module.hasClass(className.bottom); + }, + initialPosition: function() { + return (!module.is.fixed() && !module.is.bound()); + }, + hidden: function() { + return (!$module.is(':visible')); + }, + bound: function() { + return $module.hasClass(className.bound); + }, + fixed: function() { + return $module.hasClass(className.fixed); + } + }, + + stick: function(scroll) { + var + cachedPosition = scroll || $scroll.scrollTop(), + cache = module.cache, + fits = cache.fits, + sameHeight = cache.sameHeight, + element = cache.element, + scrollContext = cache.scrollContext, + context = cache.context, + offset = (module.is.bottom() && settings.pushing) + ? settings.bottomOffset + : settings.offset, + scroll = { + top : cachedPosition + offset, + bottom : cachedPosition + offset + scrollContext.height + }, + elementScroll = (fits) + ? 0 + : module.get.elementScroll(scroll.top), + + // shorthand + doesntFit = !fits, + elementVisible = (element.height !== 0) + ; + if(elementVisible && !sameHeight) { + + if( module.is.initialPosition() ) { + if(scroll.top >= context.bottom) { + module.debug('Initial element position is bottom of container'); + module.bindBottom(); + } + else if(scroll.top > element.top) { + if( (element.height + scroll.top - elementScroll) >= context.bottom ) { + module.debug('Initial element position is bottom of container'); + module.bindBottom(); + } + else { + module.debug('Initial element position is fixed'); + module.fixTop(); + } + } + + } + else if( module.is.fixed() ) { + + // currently fixed top + if( module.is.top() ) { + if( scroll.top <= element.top ) { + module.debug('Fixed element reached top of container'); + module.setInitialPosition(); + } + else if( (element.height + scroll.top - elementScroll) >= context.bottom ) { + module.debug('Fixed element reached bottom of container'); + module.bindBottom(); + } + // scroll element if larger than screen + else if(doesntFit) { + module.set.scroll(elementScroll); + module.save.lastScroll(scroll.top); + module.save.elementScroll(elementScroll); + } + } + + // currently fixed bottom + else if(module.is.bottom() ) { + + // top edge + if( (scroll.bottom - element.height) <= element.top) { + module.debug('Bottom fixed rail has reached top of container'); + module.setInitialPosition(); + } + // bottom edge + else if(scroll.bottom >= context.bottom) { + module.debug('Bottom fixed rail has reached bottom of container'); + module.bindBottom(); + } + // scroll element if larger than screen + else if(doesntFit) { + module.set.scroll(elementScroll); + module.save.lastScroll(scroll.top); + module.save.elementScroll(elementScroll); + } + + } + } + else if( module.is.bottom() ) { + if( scroll.top <= element.top ) { + module.debug('Jumped from bottom fixed to top fixed, most likely used home/end button'); + module.setInitialPosition(); + } + else { + if(settings.pushing) { + if(module.is.bound() && scroll.bottom <= context.bottom ) { + module.debug('Fixing bottom attached element to bottom of browser.'); + module.fixBottom(); + } + } + else { + if(module.is.bound() && (scroll.top <= context.bottom - element.height) ) { + module.debug('Fixing bottom attached element to top of browser.'); + module.fixTop(); + } + } + } + } + } + }, + + bindTop: function() { + module.debug('Binding element to top of parent container'); + module.remove.offset(); + $module + .css({ + left : '', + top : '', + marginBottom : '' + }) + .removeClass(className.fixed) + .removeClass(className.bottom) + .addClass(className.bound) + .addClass(className.top) + ; + settings.onTop.call(element); + settings.onUnstick.call(element); + }, + bindBottom: function() { + module.debug('Binding element to bottom of parent container'); + module.remove.offset(); + $module + .css({ + left : '', + top : '' + }) + .removeClass(className.fixed) + .removeClass(className.top) + .addClass(className.bound) + .addClass(className.bottom) + ; + settings.onBottom.call(element); + settings.onUnstick.call(element); + }, + + setInitialPosition: function() { + module.debug('Returning to initial position'); + module.unfix(); + module.unbind(); + }, + + + fixTop: function() { + module.debug('Fixing element to top of page'); + if(settings.setSize) { + module.set.size(); + } + module.set.minimumSize(); + module.set.offset(); + $module + .css({ + left : module.cache.element.left, + bottom : '', + marginBottom : '' + }) + .removeClass(className.bound) + .removeClass(className.bottom) + .addClass(className.fixed) + .addClass(className.top) + ; + settings.onStick.call(element); + }, + + fixBottom: function() { + module.debug('Sticking element to bottom of page'); + if(settings.setSize) { + module.set.size(); + } + module.set.minimumSize(); + module.set.offset(); + $module + .css({ + left : module.cache.element.left, + bottom : '', + marginBottom : '' + }) + .removeClass(className.bound) + .removeClass(className.top) + .addClass(className.fixed) + .addClass(className.bottom) + ; + settings.onStick.call(element); + }, + + unbind: function() { + if( module.is.bound() ) { + module.debug('Removing container bound position on element'); + module.remove.offset(); + $module + .removeClass(className.bound) + .removeClass(className.top) + .removeClass(className.bottom) + ; + } + }, + + unfix: function() { + if( module.is.fixed() ) { + module.debug('Removing fixed position on element'); + module.remove.minimumSize(); + module.remove.offset(); + $module + .removeClass(className.fixed) + .removeClass(className.top) + .removeClass(className.bottom) + ; + settings.onUnstick.call(element); + } + }, + + reset: function() { + module.debug('Resetting elements position'); + module.unbind(); + module.unfix(); + module.resetCSS(); + module.remove.offset(); + module.remove.lastScroll(); + }, + + resetCSS: function() { + $module + .css({ + width : '', + height : '' + }) + ; + $container + .css({ + height: '' + }) + ; + }, + + setting: function(name, value) { + if( $.isPlainObject(name) ) { + $.extend(true, settings, name); + } + else if(value !== undefined) { + 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, 0); + }, + 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 { + return false; + } + }); + } + if ( $.isFunction( found ) ) { + response = found.apply(context, passedArguments); + } + else if(found !== undefined) { + response = found; + } + if(Array.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.sticky.settings = { + + name : 'Sticky', + namespace : 'sticky', + + silent : false, + debug : false, + verbose : true, + performance : true, + + // whether to stick in the opposite direction on scroll up + pushing : false, + + context : false, + container : false, + + // Context to watch scroll events + scrollContext : window, + + // Offset to adjust scroll + offset : 0, + + // Offset to adjust scroll when attached to bottom of screen + bottomOffset : 0, + + // will only set container height if difference between context and container is larger than this number + jitter : 5, + + // set width of sticky element when it is fixed to page (used to make sure 100% width is maintained if no fixed size set) + setSize : true, + + // Whether to automatically observe changes with Mutation Observers + observeChanges : false, + + // Called when position is recalculated + onReposition : function(){}, + + // Called on each scroll + onScroll : function(){}, + + // Called when element is stuck to viewport + onStick : function(){}, + + // Called when element is unstuck from viewport + onUnstick : function(){}, + + // Called when element reaches top of context + onTop : function(){}, + + // Called when element reaches bottom of context + onBottom : function(){}, + + error : { + container : 'Sticky element must be inside a relative container', + visible : 'Element is hidden, you must call refresh after element becomes visible. Use silent setting to surpress this warning in production.', + method : 'The method you called is not defined.', + invalidContext : 'Context specified does not exist', + elementSize : 'Sticky element is larger than its container, cannot create sticky.' + }, + + className : { + bound : 'bound', + fixed : 'fixed', + supported : 'native', + top : 'top', + bottom : 'bottom' + } + +}; + +})( jQuery, window, document ); diff --git a/semantic/src/definitions/modules/sticky.less b/semantic/src/definitions/modules/sticky.less new file mode 100644 index 0000000..2dabc6d --- /dev/null +++ b/semantic/src/definitions/modules/sticky.less @@ -0,0 +1,74 @@ +/*! + * # Fomantic-UI - Sticky + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + + +/******************************* + Theme +*******************************/ + +@type : 'module'; +@element : 'sticky'; + +@import (multiple) '../../theme.config'; + +/******************************* + Sticky +*******************************/ + +.ui.sticky { + position: static; + transition: @transition; + z-index: @zIndex; +} + +/******************************* + States +*******************************/ + +/* Bound */ +.ui.sticky.bound { + position: absolute; + left: auto; + right: auto; +} + +/* Fixed */ +.ui.sticky.fixed { + position: fixed; + left: auto; + right: auto; +} + +/* Bound/Fixed Position */ +.ui.sticky.bound.top, +.ui.sticky.fixed.top { + top: 0; + bottom: auto; +} +.ui.sticky.bound.bottom, +.ui.sticky.fixed.bottom { + top: auto; + bottom: 0; +} + + +/******************************* + Types +*******************************/ + +.ui.native.sticky { + position: -webkit-sticky; + position: -moz-sticky; + position: -ms-sticky; + position: -o-sticky; + position: sticky; +} + +.loadUIOverrides(); diff --git a/semantic/src/definitions/modules/tab.js b/semantic/src/definitions/modules/tab.js new file mode 100644 index 0000000..eae3cfc --- /dev/null +++ b/semantic/src/definitions/modules/tab.js @@ -0,0 +1,1001 @@ +/*! + * # Fomantic-UI - Tab + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +'use strict'; + +$.isWindow = $.isWindow || function(obj) { + return obj != null && obj === obj.window; +}; +$.isFunction = $.isFunction || function(obj) { + return typeof obj === "function" && typeof obj.nodeType !== "number"; +}; + +window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.fn.tab = function(parameters) { + + var + // use window context if none specified + $allModules = $.isFunction(this) + ? $(window) + : $(this), + + moduleSelector = $allModules.selector || '', + time = new Date().getTime(), + performance = [], + + query = arguments[0], + methodInvoked = (typeof query == 'string'), + queryArguments = [].slice.call(arguments, 1), + + initializedHistory = false, + returnedValue + ; + + $allModules + .each(function() { + var + + settings = ( $.isPlainObject(parameters) ) + ? $.extend(true, {}, $.fn.tab.settings, parameters) + : $.extend({}, $.fn.tab.settings), + + className = settings.className, + metadata = settings.metadata, + selector = settings.selector, + error = settings.error, + regExp = settings.regExp, + + eventNamespace = '.' + settings.namespace, + moduleNamespace = 'module-' + settings.namespace, + + $module = $(this), + $context, + $tabs, + + cache = {}, + firstLoad = true, + recursionDepth = 0, + element = this, + instance = $module.data(moduleNamespace), + + activeTabPath, + parameterArray, + module, + + historyEvent + + ; + + module = { + + initialize: function() { + module.debug('Initializing tab menu item', $module); + module.fix.callbacks(); + module.determineTabs(); + + module.debug('Determining tabs', settings.context, $tabs); + // set up automatic routing + if(settings.auto) { + module.set.auto(); + } + module.bind.events(); + + if(settings.history && !initializedHistory) { + module.initializeHistory(); + initializedHistory = true; + } + + if(settings.autoTabActivation && instance === undefined && module.determine.activeTab() == null) { + module.debug('No active tab detected, setting first tab active', module.get.initialPath()); + module.changeTab(settings.autoTabActivation === true ? module.get.initialPath() : settings.autoTabActivation); + }; + + module.instantiate(); + }, + + instantiate: function () { + module.verbose('Storing instance of module', module); + instance = module; + $module + .data(moduleNamespace, module) + ; + }, + + destroy: function() { + module.debug('Destroying tabs', $module); + $module + .removeData(moduleNamespace) + .off(eventNamespace) + ; + }, + + bind: { + events: function() { + // if using $.tab don't add events + if( !$.isWindow( element ) ) { + module.debug('Attaching tab activation events to element', $module); + $module + .on('click' + eventNamespace, module.event.click) + ; + } + } + }, + + determineTabs: function() { + var + $reference + ; + + // determine tab context + if(settings.context === 'parent') { + if($module.closest(selector.ui).length > 0) { + $reference = $module.closest(selector.ui); + module.verbose('Using closest UI element as parent', $reference); + } + else { + $reference = $module; + } + $context = $reference.parent(); + module.verbose('Determined parent element for creating context', $context); + } + else if(settings.context) { + $context = $(settings.context); + module.verbose('Using selector for tab context', settings.context, $context); + } + else { + $context = $('body'); + } + // find tabs + if(settings.childrenOnly) { + $tabs = $context.children(selector.tabs); + module.debug('Searching tab context children for tabs', $context, $tabs); + } + else { + $tabs = $context.find(selector.tabs); + module.debug('Searching tab context for tabs', $context, $tabs); + } + }, + + fix: { + callbacks: function() { + if( $.isPlainObject(parameters) && (parameters.onTabLoad || parameters.onTabInit) ) { + if(parameters.onTabLoad) { + parameters.onLoad = parameters.onTabLoad; + delete parameters.onTabLoad; + module.error(error.legacyLoad, parameters.onLoad); + } + if(parameters.onTabInit) { + parameters.onFirstLoad = parameters.onTabInit; + delete parameters.onTabInit; + module.error(error.legacyInit, parameters.onFirstLoad); + } + settings = $.extend(true, {}, $.fn.tab.settings, parameters); + } + } + }, + + initializeHistory: function() { + module.debug('Initializing page state'); + if( $.address === undefined ) { + module.error(error.state); + return false; + } + else { + if(settings.historyType == 'state') { + module.debug('Using HTML5 to manage state'); + if(settings.path !== false) { + $.address + .history(true) + .state(settings.path) + ; + } + else { + module.error(error.path); + return false; + } + } + $.address + .bind('change', module.event.history.change) + ; + } + }, + + event: { + click: function(event) { + var + tabPath = $(this).data(metadata.tab) + ; + if(tabPath !== undefined) { + if(settings.history) { + module.verbose('Updating page state', event); + $.address.value(tabPath); + } + else { + module.verbose('Changing tab', event); + module.changeTab(tabPath); + } + event.preventDefault(); + } + else { + module.debug('No tab specified'); + } + }, + history: { + change: function(event) { + var + tabPath = event.pathNames.join('/') || module.get.initialPath(), + pageTitle = settings.templates.determineTitle(tabPath) || false + ; + module.performance.display(); + module.debug('History change event', tabPath, event); + historyEvent = event; + if(tabPath !== undefined) { + module.changeTab(tabPath); + } + if(pageTitle) { + $.address.title(pageTitle); + } + } + } + }, + + refresh: function() { + if(activeTabPath) { + module.debug('Refreshing tab', activeTabPath); + module.changeTab(activeTabPath); + } + }, + + cache: { + + read: function(cacheKey) { + return (cacheKey !== undefined) + ? cache[cacheKey] + : false + ; + }, + add: function(cacheKey, content) { + cacheKey = cacheKey || activeTabPath; + module.debug('Adding cached content for', cacheKey); + cache[cacheKey] = content; + }, + remove: function(cacheKey) { + cacheKey = cacheKey || activeTabPath; + module.debug('Removing cached content for', cacheKey); + delete cache[cacheKey]; + } + }, + + escape: { + string: function(text) { + text = String(text); + return text.replace(regExp.escape, '\\$&'); + } + }, + + set: { + auto: function() { + var + url = (typeof settings.path == 'string') + ? settings.path.replace(/\/$/, '') + '/{$tab}' + : '/{$tab}' + ; + module.verbose('Setting up automatic tab retrieval from server', url); + if($.isPlainObject(settings.apiSettings)) { + settings.apiSettings.url = url; + } + else { + settings.apiSettings = { + url: url + }; + } + }, + loading: function(tabPath) { + var + $tab = module.get.tabElement(tabPath), + isLoading = $tab.hasClass(className.loading) + ; + if(!isLoading) { + module.verbose('Setting loading state for', $tab); + $tab + .addClass(className.loading) + .siblings($tabs) + .removeClass(className.active + ' ' + className.loading) + ; + if($tab.length > 0) { + settings.onRequest.call($tab[0], tabPath); + } + } + }, + state: function(state) { + $.address.value(state); + } + }, + + changeTab: function(tabPath) { + var + pushStateAvailable = (window.history && window.history.pushState), + shouldIgnoreLoad = (pushStateAvailable && settings.ignoreFirstLoad && firstLoad), + remoteContent = (settings.auto || $.isPlainObject(settings.apiSettings) ), + // only add default path if not remote content + pathArray = (remoteContent && !shouldIgnoreLoad) + ? module.utilities.pathToArray(tabPath) + : module.get.defaultPathArray(tabPath) + ; + tabPath = module.utilities.arrayToPath(pathArray); + $.each(pathArray, function(index, tab) { + var + currentPathArray = pathArray.slice(0, index + 1), + currentPath = module.utilities.arrayToPath(currentPathArray), + + isTab = module.is.tab(currentPath), + isLastIndex = (index + 1 == pathArray.length), + + $tab = module.get.tabElement(currentPath), + $anchor, + nextPathArray, + nextPath, + isLastTab + ; + module.verbose('Looking for tab', tab); + if(isTab) { + module.verbose('Tab was found', tab); + // scope up + activeTabPath = currentPath; + parameterArray = module.utilities.filterArray(pathArray, currentPathArray); + + if(isLastIndex) { + isLastTab = true; + } + else { + nextPathArray = pathArray.slice(0, index + 2); + nextPath = module.utilities.arrayToPath(nextPathArray); + isLastTab = ( !module.is.tab(nextPath) ); + if(isLastTab) { + module.verbose('Tab parameters found', nextPathArray); + } + } + if(isLastTab && remoteContent) { + if(!shouldIgnoreLoad) { + module.activate.navigation(currentPath); + module.fetch.content(currentPath, tabPath); + } + else { + module.debug('Ignoring remote content on first tab load', currentPath); + firstLoad = false; + module.cache.add(tabPath, $tab.html()); + module.activate.all(currentPath); + settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent); + settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent); + } + return false; + } + else { + module.debug('Opened local tab', currentPath); + module.activate.all(currentPath); + if( !module.cache.read(currentPath) ) { + module.cache.add(currentPath, true); + module.debug('First time tab loaded calling tab init'); + settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent); + } + settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent); + } + + } + else if(tabPath.search('/') == -1 && tabPath !== '') { + // look for in page anchor + tabPath = module.escape.string(tabPath); + $anchor = $('#' + tabPath + ', a[name="' + tabPath + '"]'); + currentPath = $anchor.closest('[data-tab]').data(metadata.tab); + $tab = module.get.tabElement(currentPath); + // if anchor exists use parent tab + if($anchor && $anchor.length > 0 && currentPath) { + module.debug('Anchor link used, opening parent tab', $tab, $anchor); + if( !$tab.hasClass(className.active) ) { + setTimeout(function() { + module.scrollTo($anchor); + }, 0); + } + module.activate.all(currentPath); + if( !module.cache.read(currentPath) ) { + module.cache.add(currentPath, true); + module.debug('First time tab loaded calling tab init'); + settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent); + } + settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent); + return false; + } + } + else { + module.error(error.missingTab, $module, $context, currentPath); + return false; + } + }); + }, + + scrollTo: function($element) { + var + scrollOffset = ($element && $element.length > 0) + ? $element.offset().top + : false + ; + if(scrollOffset !== false) { + module.debug('Forcing scroll to an in-page link in a hidden tab', scrollOffset, $element); + $(document).scrollTop(scrollOffset); + } + }, + + update: { + content: function(tabPath, html, evaluateScripts) { + var + $tab = module.get.tabElement(tabPath), + tab = $tab[0] + ; + evaluateScripts = (evaluateScripts !== undefined) + ? evaluateScripts + : settings.evaluateScripts + ; + if(typeof settings.cacheType == 'string' && settings.cacheType.toLowerCase() == 'dom' && typeof html !== 'string') { + $tab + .empty() + .append($(html).clone(true)) + ; + } + else { + if(evaluateScripts) { + module.debug('Updating HTML and evaluating inline scripts', tabPath, html); + $tab.html(html); + } + else { + module.debug('Updating HTML', tabPath, html); + tab.innerHTML = html; + } + } + } + }, + + fetch: { + + content: function(tabPath, fullTabPath) { + var + $tab = module.get.tabElement(tabPath), + apiSettings = { + dataType : 'html', + encodeParameters : false, + on : 'now', + cache : settings.alwaysRefresh, + headers : { + 'X-Remote': true + }, + onSuccess : function(response) { + if(settings.cacheType == 'response') { + module.cache.add(fullTabPath, response); + } + module.update.content(tabPath, response); + if(tabPath == activeTabPath) { + module.debug('Content loaded', tabPath); + module.activate.tab(tabPath); + } + else { + module.debug('Content loaded in background', tabPath); + } + settings.onFirstLoad.call($tab[0], tabPath, parameterArray, historyEvent); + settings.onLoad.call($tab[0], tabPath, parameterArray, historyEvent); + + if(settings.loadOnce) { + module.cache.add(fullTabPath, true); + } + else if(typeof settings.cacheType == 'string' && settings.cacheType.toLowerCase() == 'dom' && $tab.children().length > 0) { + setTimeout(function() { + var + $clone = $tab.children().clone(true) + ; + $clone = $clone.not('script'); + module.cache.add(fullTabPath, $clone); + }, 0); + } + else { + module.cache.add(fullTabPath, $tab.html()); + } + }, + urlData: { + tab: fullTabPath + } + }, + request = $tab.api('get request') || false, + existingRequest = ( request && request.state() === 'pending' ), + requestSettings, + cachedContent + ; + + fullTabPath = fullTabPath || tabPath; + cachedContent = module.cache.read(fullTabPath); + + + if(settings.cache && cachedContent) { + module.activate.tab(tabPath); + module.debug('Adding cached content', fullTabPath); + if(!settings.loadOnce) { + if(settings.evaluateScripts == 'once') { + module.update.content(tabPath, cachedContent, false); + } + else { + module.update.content(tabPath, cachedContent); + } + } + settings.onLoad.call($tab[0], tabPath, parameterArray, historyEvent); + } + else if(existingRequest) { + module.set.loading(tabPath); + module.debug('Content is already loading', fullTabPath); + } + else if($.api !== undefined) { + requestSettings = $.extend(true, {}, settings.apiSettings, apiSettings); + module.debug('Retrieving remote content', fullTabPath, requestSettings); + module.set.loading(tabPath); + $tab.api(requestSettings); + } + else { + module.error(error.api); + } + } + }, + + activate: { + all: function(tabPath) { + module.activate.tab(tabPath); + module.activate.navigation(tabPath); + }, + tab: function(tabPath) { + var + $tab = module.get.tabElement(tabPath), + $deactiveTabs = (settings.deactivate == 'siblings') + ? $tab.siblings($tabs) + : $tabs.not($tab), + isActive = $tab.hasClass(className.active) + ; + module.verbose('Showing tab content for', $tab); + if(!isActive) { + $tab + .addClass(className.active) + ; + $deactiveTabs + .removeClass(className.active + ' ' + className.loading) + ; + if($tab.length > 0) { + settings.onVisible.call($tab[0], tabPath); + } + } + }, + navigation: function(tabPath) { + var + $navigation = module.get.navElement(tabPath), + $deactiveNavigation = (settings.deactivate == 'siblings') + ? $navigation.siblings($allModules) + : $allModules.not($navigation), + isActive = $navigation.hasClass(className.active) + ; + module.verbose('Activating tab navigation for', $navigation, tabPath); + if(!isActive) { + $navigation + .addClass(className.active) + ; + $deactiveNavigation + .removeClass(className.active + ' ' + className.loading) + ; + } + } + }, + + deactivate: { + all: function() { + module.deactivate.navigation(); + module.deactivate.tabs(); + }, + navigation: function() { + $allModules + .removeClass(className.active) + ; + }, + tabs: function() { + $tabs + .removeClass(className.active + ' ' + className.loading) + ; + } + }, + + is: { + tab: function(tabName) { + return (tabName !== undefined) + ? ( module.get.tabElement(tabName).length > 0 ) + : false + ; + } + }, + + get: { + initialPath: function() { + return $allModules.eq(0).data(metadata.tab) || $tabs.eq(0).data(metadata.tab); + }, + path: function() { + return $.address.value(); + }, + // adds default tabs to tab path + defaultPathArray: function(tabPath) { + return module.utilities.pathToArray( module.get.defaultPath(tabPath) ); + }, + defaultPath: function(tabPath) { + var + $defaultNav = $allModules.filter('[data-' + metadata.tab + '^="' + module.escape.string(tabPath) + '/"]').eq(0), + defaultTab = $defaultNav.data(metadata.tab) || false + ; + if( defaultTab ) { + module.debug('Found default tab', defaultTab); + if(recursionDepth < settings.maxDepth) { + recursionDepth++; + return module.get.defaultPath(defaultTab); + } + module.error(error.recursion); + } + else { + module.debug('No default tabs found for', tabPath, $tabs); + } + recursionDepth = 0; + return tabPath; + }, + navElement: function(tabPath) { + tabPath = tabPath || activeTabPath; + return $allModules.filter('[data-' + metadata.tab + '="' + module.escape.string(tabPath) + '"]'); + }, + tabElement: function(tabPath) { + var + $fullPathTab, + $simplePathTab, + tabPathArray, + lastTab + ; + tabPath = tabPath || activeTabPath; + tabPathArray = module.utilities.pathToArray(tabPath); + lastTab = module.utilities.last(tabPathArray); + $fullPathTab = $tabs.filter('[data-' + metadata.tab + '="' + module.escape.string(tabPath) + '"]'); + $simplePathTab = $tabs.filter('[data-' + metadata.tab + '="' + module.escape.string(lastTab) + '"]'); + return ($fullPathTab.length > 0) + ? $fullPathTab + : $simplePathTab + ; + }, + tab: function() { + return activeTabPath; + } + }, + + determine: { + activeTab: function() { + var activeTab = null; + + $tabs.each(function(_index, tab) { + var $tab = $(tab); + + if( $tab.hasClass(className.active) ) { + var + tabPath = $(this).data(metadata.tab), + $anchor = $allModules.filter('[data-' + metadata.tab + '="' + module.escape.string(tabPath) + '"]') + ; + + if( $anchor.hasClass(className.active) ) { + activeTab = tabPath; + } + } + }); + + return activeTab; + } + }, + + utilities: { + filterArray: function(keepArray, removeArray) { + return $.grep(keepArray, function(keepValue) { + return ( $.inArray(keepValue, removeArray) == -1); + }); + }, + last: function(array) { + return Array.isArray(array) + ? array[ array.length - 1] + : false + ; + }, + pathToArray: function(pathName) { + if(pathName === undefined) { + pathName = activeTabPath; + } + return typeof pathName == 'string' + ? pathName.split('/') + : [pathName] + ; + }, + arrayToPath: function(pathArray) { + return Array.isArray(pathArray) + ? pathArray.join('/') + : false + ; + } + }, + + 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(Array.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 + ; + +}; + +// shortcut for tabbed content with no defined navigation +$.tab = function() { + $(window).tab.apply(this, arguments); +}; + +$.fn.tab.settings = { + + name : 'Tab', + namespace : 'tab', + + silent : false, + debug : false, + verbose : false, + performance : true, + + auto : false, // uses pjax style endpoints fetching content from same url with remote-content headers + history : false, // use browser history + historyType : 'hash', // #/ or html5 state + path : false, // base path of url + + context : false, // specify a context that tabs must appear inside + childrenOnly : false, // use only tabs that are children of context + maxDepth : 25, // max depth a tab can be nested + + deactivate : 'siblings', // whether tabs should deactivate sibling menu elements or all elements initialized together + + alwaysRefresh : false, // load tab content new every tab click + cache : true, // cache the content requests to pull locally + loadOnce : false, // Whether tab data should only be loaded once when using remote content + cacheType : 'response', // Whether to cache exact response, or to html cache contents after scripts execute + ignoreFirstLoad : false, // don't load remote content on first load + + apiSettings : false, // settings for api call + evaluateScripts : 'once', // whether inline scripts should be parsed (true/false/once). Once will not re-evaluate on cached content + autoTabActivation: true, // whether a non existing active tab will auto activate the first available tab + + onFirstLoad : function(tabPath, parameterArray, historyEvent) {}, // called first time loaded + onLoad : function(tabPath, parameterArray, historyEvent) {}, // called on every load + onVisible : function(tabPath, parameterArray, historyEvent) {}, // called every time tab visible + onRequest : function(tabPath, parameterArray, historyEvent) {}, // called ever time a tab beings loading remote content + + templates : { + determineTitle: function(tabArray) {} // returns page title for path + }, + + error: { + api : 'You attempted to load content without API module', + method : 'The method you called is not defined', + missingTab : 'Activated tab cannot be found. Tabs are case-sensitive.', + noContent : 'The tab you specified is missing a content url.', + path : 'History enabled, but no path was specified', + recursion : 'Max recursive depth reached', + legacyInit : 'onTabInit has been renamed to onFirstLoad in 2.0, please adjust your code.', + legacyLoad : 'onTabLoad has been renamed to onLoad in 2.0. Please adjust your code', + state : 'History requires Asual\'s Address library <https://github.com/asual/jquery-address>' + }, + + regExp : { + escape : /[-[\]{}()*+?.,\\^$|#\s:=@]/g + }, + + metadata : { + tab : 'tab', + loaded : 'loaded', + promise: 'promise' + }, + + className : { + loading : 'loading', + active : 'active' + }, + + selector : { + tabs : '.ui.tab', + ui : '.ui' + } + +}; + +})( jQuery, window, document ); diff --git a/semantic/src/definitions/modules/tab.less b/semantic/src/definitions/modules/tab.less new file mode 100644 index 0000000..3c8f509 --- /dev/null +++ b/semantic/src/definitions/modules/tab.less @@ -0,0 +1,91 @@ +/*! + * # Fomantic-UI - Tab + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + + +/******************************* + Theme +*******************************/ + +@type : 'module'; +@element : 'tab'; + +@import (multiple) '../../theme.config'; + +/******************************* + UI Tabs +*******************************/ + +.ui.tab { + display: none; +} + +/******************************* + States +*******************************/ + +/*-------------------- + Active +---------------------*/ + +.ui.tab.active, +.ui.tab.open { + display: block; +} + +& when (@variationTabLoading) { + /*-------------------- + Loading + ---------------------*/ + + .ui.tab.loading { + position: relative; + overflow: hidden; + display: block; + min-height: @loadingMinHeight; + } + .ui.tab.loading * { + position: @loadingContentPosition !important; + left: @loadingContentOffset !important; + } + + .ui.tab.loading:before, + .ui.tab.loading.segment:before { + position: absolute; + content: ''; + top: @loaderDistanceFromTop; + left: 50%; + + margin: @loaderMargin; + width: @loaderSize; + height: @loaderSize; + + border-radius: @circularRadius; + border: @loaderLineWidth solid @loaderFillColor; + } + .ui.tab.loading:after, + .ui.tab.loading.segment:after { + position: absolute; + content: ''; + top: @loaderDistanceFromTop; + left: 50%; + + margin: @loaderMargin; + width: @loaderSize; + height: @loaderSize; + + animation: loader @loaderSpeed infinite linear; + border: @loaderLineWidth solid @loaderLineColor; + border-radius: @circularRadius; + + box-shadow: 0 0 0 1px transparent; + } +} + +.loadUIOverrides(); diff --git a/semantic/src/definitions/modules/toast.js b/semantic/src/definitions/modules/toast.js new file mode 100644 index 0000000..02064ff --- /dev/null +++ b/semantic/src/definitions/modules/toast.js @@ -0,0 +1,872 @@ +/*! + * # Fomantic-UI - Toast + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +'use strict'; + +$.isFunction = $.isFunction || function(obj) { + return typeof obj === "function" && typeof obj.nodeType !== "number"; +}; + +window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.fn.toast = 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), + returnedValue + ; + $allModules + .each(function() { + var + settings = ( $.isPlainObject(parameters) ) + ? $.extend(true, {}, $.fn.toast.settings, parameters) + : $.extend({}, $.fn.toast.settings), + + className = settings.className, + selector = settings.selector, + error = settings.error, + namespace = settings.namespace, + fields = settings.fields, + + eventNamespace = '.' + namespace, + moduleNamespace = namespace + '-module', + + $module = $(this), + $toastBox, + $toast, + $actions, + $progress, + $progressBar, + $animationObject, + $close, + $context = (settings.context) + ? $(settings.context) + : $('body'), + + isToastComponent = $module.hasClass('toast') || $module.hasClass('message') || $module.hasClass('card'), + + element = this, + instance = isToastComponent ? $module.data(moduleNamespace) : undefined, + + module + ; + module = { + + initialize: function() { + module.verbose('Initializing element'); + if (!module.has.container()) { + module.create.container(); + } + if(isToastComponent || settings.message !== '' || settings.title !== '' || module.get.iconClass() !== '' || settings.showImage || module.has.configActions()) { + if(typeof settings.showProgress !== 'string' || [className.top,className.bottom].indexOf(settings.showProgress) === -1 ) { + settings.showProgress = false; + } + module.create.toast(); + if(settings.closeOnClick && (settings.closeIcon || $($toast).find(selector.input).length > 0 || module.has.configActions())){ + settings.closeOnClick = false; + } + if(!settings.closeOnClick) { + $toastBox.addClass(className.unclickable); + } + module.bind.events(); + } + module.instantiate(); + if($toastBox) { + module.show(); + } + }, + + instantiate: function() { + module.verbose('Storing instance of toast'); + instance = module; + $module + .data(moduleNamespace, instance) + ; + }, + + destroy: function() { + if($toastBox) { + module.debug('Removing toast', $toastBox); + module.unbind.events(); + $toastBox.remove(); + $toastBox = undefined; + $toast = undefined; + $animationObject = undefined; + settings.onRemove.call($toastBox, element); + $progress = undefined; + $progressBar = undefined; + $close = undefined; + } + $module + .removeData(moduleNamespace) + ; + }, + + show: function(callback) { + callback = callback || function(){}; + module.debug('Showing toast'); + if(settings.onShow.call($toastBox, element) === false) { + module.debug('onShow callback returned false, cancelling toast animation'); + return; + } + module.animate.show(callback); + }, + + close: function(callback) { + callback = callback || function(){}; + module.remove.visible(); + module.unbind.events(); + module.animate.close(callback); + + }, + + create: { + container: function() { + module.verbose('Creating container'); + $context.append($('<div/>',{class: settings.position + ' ' + className.container})); + }, + toast: function() { + $toastBox = $('<div/>', {class: className.box}); + if (!isToastComponent) { + module.verbose('Creating toast'); + $toast = $('<div/>'); + var $content = $('<div/>', {class: className.content}); + var iconClass = module.get.iconClass(); + if (iconClass !== '') { + $toast.append($('<i/>', {class: iconClass + ' ' + className.icon})); + } + + if (settings.showImage) { + $toast.append($('<img>', { + class: className.image + ' ' + settings.classImage, + src: settings.showImage + })); + } + if (settings.title !== '') { + $content.append($('<div/>', { + class: className.title, + text: settings.title + })); + } + + $content.append($('<div/>', {html: module.helpers.escape(settings.message, settings.preserveHTML)})); + + $toast + .addClass(settings.class + ' ' + className.toast) + .append($content) + ; + $toast.css('opacity', settings.opacity); + if (settings.closeIcon) { + $close = $('<i/>', {class: className.close + ' ' + (typeof settings.closeIcon === 'string' ? settings.closeIcon : '')}); + if($close.hasClass(className.left)) { + $toast.prepend($close); + } else { + $toast.append($close); + } + } + } else { + $toast = settings.cloneModule ? $module.clone().removeAttr('id') : $module; + $close = $toast.find('> i'+module.helpers.toClass(className.close)); + settings.closeIcon = ($close.length > 0); + } + if ($toast.hasClass(className.compact)) { + settings.compact = true; + } + if ($toast.hasClass('card')) { + settings.compact = false; + } + $actions = $toast.find('.actions'); + if (module.has.configActions()) { + if ($actions.length === 0) { + $actions = $('<div/>', {class: className.actions + ' ' + (settings.classActions || '')}).appendTo($toast); + } + if($toast.hasClass('card') && !$actions.hasClass(className.attached)) { + $actions.addClass(className.extraContent); + if($actions.hasClass(className.vertical)) { + $actions.removeClass(className.vertical); + module.error(error.verticalCard); + } + } + settings.actions.forEach(function (el) { + var icon = el[fields.icon] ? '<i class="' + module.helpers.deQuote(el[fields.icon]) + ' icon"></i>' : '', + text = module.helpers.escape(el[fields.text] || '', settings.preserveHTML), + cls = module.helpers.deQuote(el[fields.class] || ''), + click = el[fields.click] && $.isFunction(el[fields.click]) ? el[fields.click] : function () {}; + $actions.append($('<button/>', { + html: icon + text, + class: className.button + ' ' + cls, + click: function () { + if (click.call(element, $module) === false) { + return; + } + module.close(); + } + })); + }); + } + if ($actions && $actions.hasClass(className.vertical)) { + $toast.addClass(className.vertical); + } + if($actions.length > 0 && !$actions.hasClass(className.attached)) { + if ($actions && (!$actions.hasClass(className.basic) || $actions.hasClass(className.left))) { + $toast.addClass(className.actions); + } + } + if(settings.displayTime === 'auto'){ + settings.displayTime = Math.max(settings.minDisplayTime, $toast.text().split(" ").length / settings.wordsPerMinute * 60000); + } + $toastBox.append($toast); + + if($actions.length > 0 && $actions.hasClass(className.attached)) { + $actions.addClass(className.buttons); + $actions.detach(); + $toast.addClass(className.attached); + if (!$actions.hasClass(className.vertical)) { + if ($actions.hasClass(className.top)) { + $toastBox.prepend($actions); + $toast.addClass(className.bottom); + } else { + $toastBox.append($actions); + $toast.addClass(className.top); + } + } else { + $toast.wrap( + $('<div/>',{ + class:className.vertical + ' ' + + className.attached + ' ' + + (settings.compact ? className.compact : '') + }) + ); + if($actions.hasClass(className.left)) { + $toast.addClass(className.left).parent().addClass(className.left).prepend($actions); + } else { + $toast.parent().append($actions); + } + } + } + if($module !== $toast) { + $module = $toast; + element = $toast[0]; + } + if(settings.displayTime > 0) { + var progressingClass = className.progressing+' '+(settings.pauseOnHover ? className.pausable:''); + if (!!settings.showProgress) { + $progress = $('<div/>', { + class: className.progress + ' ' + (settings.classProgress || settings.class), + 'data-percent': '' + }); + if(!settings.classProgress) { + if ($toast.hasClass('toast') && !$toast.hasClass(className.inverted)) { + $progress.addClass(className.inverted); + } else { + $progress.removeClass(className.inverted); + } + } + $progressBar = $('<div/>', {class: 'bar '+(settings.progressUp ? 'up ' : 'down ')+progressingClass}); + $progress + .addClass(settings.showProgress) + .append($progressBar); + if ($progress.hasClass(className.top)) { + $toastBox.prepend($progress); + } else { + $toastBox.append($progress); + } + $progressBar.css('animation-duration', settings.displayTime / 1000 + 's'); + } + $animationObject = $('<span/>',{class:'wait '+progressingClass}); + $animationObject.css('animation-duration', settings.displayTime / 1000 + 's'); + $animationObject.appendTo($toast); + } + if (settings.compact) { + $toastBox.addClass(className.compact); + $toast.addClass(className.compact); + if($progress) { + $progress.addClass(className.compact); + } + } + if (settings.newestOnTop) { + $toastBox.prependTo(module.get.container()); + } + else { + $toastBox.appendTo(module.get.container()); + } + } + }, + + bind: { + events: function() { + module.debug('Binding events to toast'); + if(settings.closeOnClick || settings.closeIcon) { + (settings.closeIcon ? $close : $toast) + .on('click' + eventNamespace, module.event.click) + ; + } + if($animationObject) { + $animationObject.on('animationend' + eventNamespace, module.close); + } + $toastBox + .on('click' + eventNamespace, selector.approve, module.event.approve) + .on('click' + eventNamespace, selector.deny, module.event.deny) + ; + } + }, + + unbind: { + events: function() { + module.debug('Unbinding events to toast'); + if(settings.closeOnClick || settings.closeIcon) { + (settings.closeIcon ? $close : $toast) + .off('click' + eventNamespace) + ; + } + if($animationObject) { + $animationObject.off('animationend' + eventNamespace); + } + $toastBox + .off('click' + eventNamespace) + ; + } + }, + + animate: { + show: function(callback) { + callback = $.isFunction(callback) ? callback : function(){}; + if(settings.transition && module.can.useElement('transition') && $module.transition('is supported')) { + module.set.visible(); + $toastBox + .transition({ + animation : settings.transition.showMethod + ' in', + queue : false, + debug : settings.debug, + verbose : settings.verbose, + duration : settings.transition.showDuration, + onComplete : function() { + callback.call($toastBox, element); + settings.onVisible.call($toastBox, element); + } + }) + ; + } + }, + close: function(callback) { + callback = $.isFunction(callback) ? callback : function(){}; + module.debug('Closing toast'); + if(settings.onHide.call($toastBox, element) === false) { + module.debug('onHide callback returned false, cancelling toast animation'); + return; + } + if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { + $toastBox + .transition({ + animation : settings.transition.hideMethod + ' out', + queue : false, + duration : settings.transition.hideDuration, + debug : settings.debug, + verbose : settings.verbose, + interval : 50, + + onBeforeHide: function(callback){ + callback = $.isFunction(callback)?callback : function(){}; + if(settings.transition.closeEasing !== ''){ + if($toastBox) { + $toastBox.css('opacity', 0); + $toastBox.wrap('<div/>').parent().slideUp(500, settings.transition.closeEasing, function () { + if ($toastBox) { + $toastBox.parent().remove(); + callback.call($toastBox); + } + }); + } + } else { + callback.call($toastBox); + } + }, + onComplete : function() { + callback.call($toastBox, element); + settings.onHidden.call($toastBox, element); + module.destroy(); + } + }) + ; + } + else { + module.error(error.noTransition); + } + }, + pause: function() { + $animationObject.css('animationPlayState','paused'); + if($progressBar) { + $progressBar.css('animationPlayState', 'paused'); + } + }, + continue: function() { + $animationObject.css('animationPlayState','running'); + if($progressBar) { + $progressBar.css('animationPlayState', 'running'); + } + } + }, + + has: { + container: function() { + module.verbose('Determining if there is already a container'); + return ($context.find(module.helpers.toClass(settings.position) + selector.container).length > 0); + }, + toast: function(){ + return !!module.get.toast(); + }, + toasts: function(){ + return module.get.toasts().length > 0; + }, + configActions: function () { + return Array.isArray(settings.actions) && settings.actions.length > 0; + } + }, + + get: { + container: function() { + return ($context.find(module.helpers.toClass(settings.position) + selector.container)[0]); + }, + toastBox: function() { + return $toastBox || null; + }, + toast: function() { + return $toast || null; + }, + toasts: function() { + return $(module.get.container()).find(selector.box); + }, + iconClass: function() { + return typeof settings.showIcon === 'string' ? settings.showIcon : settings.showIcon && settings.icons[settings.class] ? settings.icons[settings.class] : ''; + }, + remainingTime: function() { + return $animationObject ? $animationObject.css('opacity') * settings.displayTime : 0; + } + }, + + set: { + visible: function() { + $toast.addClass(className.visible); + } + }, + + remove: { + visible: function() { + $toast.removeClass(className.visible); + } + }, + + event: { + click: function(event) { + if($(event.target).closest('a').length === 0) { + settings.onClick.call($toastBox, element); + module.close(); + } + }, + approve: function() { + if(settings.onApprove.call(element, $module) === false) { + module.verbose('Approve callback returned false cancelling close'); + return; + } + module.close(); + }, + deny: function() { + if(settings.onDeny.call(element, $module) === false) { + module.verbose('Deny callback returned false cancelling close'); + return; + } + module.close(); + } + }, + + helpers: { + toClass: function(selector) { + var + classes = selector.split(' '), + result = '' + ; + + classes.forEach(function (element) { + result += '.' + element; + }); + + return result; + }, + deQuote: function(string) { + return String(string).replace(/"/g,""); + }, + escape: function(string, preserveHTML) { + if (preserveHTML){ + return string; + } + var + badChars = /[<>"'`]/g, + shouldEscape = /[&<>"'`]/, + escape = { + "<": "<", + ">": ">", + '"': """, + "'": "'", + "`": "`" + }, + escapedChar = function(chr) { + return escape[chr]; + } + ; + if(shouldEscape.test(string)) { + string = string.replace(/&(?![a-z0-9#]{1,6};)/, "&"); + return string.replace(badChars, escapedChar); + } + return string; + } + }, + + can: { + useElement: function(element){ + if ($.fn[element] !== undefined) { + return true; + } + module.error(error.noElement.replace('{element}',element)); + return false; + } + }, + + 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(Array.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(); + returnedValue = $module; + } + }) + ; + + return (returnedValue !== undefined) + ? returnedValue + : this + ; +}; + +$.fn.toast.settings = { + + name : 'Toast', + namespace : 'toast', + + silent : false, + debug : false, + verbose : false, + performance : true, + + context : 'body', + + position : 'top right', + class : 'neutral', + classProgress : false, + classActions : false, + classImage : 'mini', + + title : '', + message : '', + displayTime : 3000, // set to zero to require manually dismissal, otherwise hides on its own + minDisplayTime : 1000, // minimum displaytime in case displayTime is set to 'auto' + wordsPerMinute : 120, + showIcon : false, + newestOnTop : false, + showProgress : false, + pauseOnHover : true, + progressUp : false, //if true, the bar will start at 0% and increase to 100% + opacity : 1, + compact : true, + closeIcon : false, + closeOnClick : true, + cloneModule : true, + actions : false, + preserveHTML : true, + showImage : false, + + // transition settings + transition : { + showMethod : 'scale', + showDuration : 500, + hideMethod : 'scale', + hideDuration : 500, + closeEasing : 'easeOutCubic' //Set to empty string to stack the closed toast area immediately (old behaviour) + }, + + error: { + method : 'The method you called is not defined.', + noElement : 'This module requires ui {element}', + verticalCard : 'Vertical but not attached actions are not supported for card layout' + }, + + className : { + container : 'ui toast-container', + box : 'floating toast-box', + progress : 'ui attached active progress', + toast : 'ui toast', + icon : 'centered icon', + visible : 'visible', + content : 'content', + title : 'ui header', + actions : 'actions', + extraContent : 'extra content', + button : 'ui button', + buttons : 'ui buttons', + close : 'close icon', + image : 'ui image', + vertical : 'vertical', + attached : 'attached', + inverted : 'inverted', + compact : 'compact', + pausable : 'pausable', + progressing : 'progressing', + top : 'top', + bottom : 'bottom', + left : 'left', + basic : 'basic', + unclickable : 'unclickable' + }, + + icons : { + info : 'info', + success : 'checkmark', + warning : 'warning', + error : 'times' + }, + + selector : { + container : '.ui.toast-container', + box : '.toast-box', + toast : '.ui.toast', + input : 'input:not([type="hidden"]), textarea, select, button, .ui.button, ui.dropdown', + approve : '.actions .positive, .actions .approve, .actions .ok', + deny : '.actions .negative, .actions .deny, .actions .cancel' + }, + + fields : { + class : 'class', + text : 'text', + icon : 'icon', + click : 'click' + }, + + // callbacks + onShow : function(){}, + onVisible : function(){}, + onClick : function(){}, + onHide : function(){}, + onHidden : function(){}, + onRemove : function(){}, + onApprove : function(){}, + onDeny : function(){} +}; + +$.extend( $.easing, { + easeOutBounce: function (x, t, b, c, d) { + if ((t/=d) < (1/2.75)) { + return c*(7.5625*t*t) + b; + } else if (t < (2/2.75)) { + return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b; + } else if (t < (2.5/2.75)) { + return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b; + } else { + return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b; + } + }, + easeOutCubic: function (t) { + return (--t)*t*t+1; + } +}); + + +})( jQuery, window, document ); diff --git a/semantic/src/definitions/modules/toast.less b/semantic/src/definitions/modules/toast.less new file mode 100644 index 0000000..1949afc --- /dev/null +++ b/semantic/src/definitions/modules/toast.less @@ -0,0 +1,590 @@ +/*! + * # Fomantic-UI - Toast + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + + +/******************************* + Theme +*******************************/ + +@type : 'module'; +@element : 'toast'; + +@import (multiple) '../../theme.config'; + +/******************************* + Toast container +*******************************/ + +.ui.toast-container { + position: fixed; + z-index: 9999; + &.top when (@variationToastTop) { + &.right when (@variationToastRight) { + top: @toastContainerDistance; + right: @toastContainerDistance; + margin-left: @toastContainerDistance; + } + &.left when (@variationToastLeft) { + top: @toastContainerDistance; + left: @toastContainerDistance; + margin-right: @toastContainerDistance; + } + &.center when (@variationToastCenter) { + left: 50%; + transform: translate(-50%, 0); + top: @toastContainerDistance; + } + } + &.bottom when (@variationToastBottom) { + &.right when (@variationToastRight) { + bottom: @toastContainerDistance; + right: @toastContainerDistance; + margin-left: @toastContainerDistance; + } + &.left when (@variationToastLeft) { + bottom: @toastContainerDistance; + left: @toastContainerDistance; + margin-right: @toastContainerDistance; + } + &.center when (@variationToastCenter) { + left: 50%; + transform: translate(-50%, 0); + bottom: @toastContainerDistance; + } + } + & .visible.toast-box, + .animating.toast-box, + .toast-box { + display: table !important; + } + & .toast-box { + margin-bottom: @toastBoxMarginBottom; + border-radius: @defaultBorderRadius; + cursor: default; + &:hover { + opacity: @toastOpacityOnHover; + } + &:not(.unclickable):hover { + cursor: @toastCursorOnHover; + } + & when (@variationToastFloating) { + &.floating, + &.hoverfloating:hover { + box-shadow: @floatingShadow; + border: @toastBoxBorder; + } + } + &.compact, + > .compact { + width: @toastWidth; + } + & > .ui.toast, + > .ui.message { + margin: @toastMargin; + position: relative; + } + & > .attached.progress when (@variationToastProgress) { + z-index:1; + &.bottom { + margin: @toastMarginProgress -@toastLeftRightMargin @toastMarginBottom; + } + &.top { + margin: @toastMarginBottom -@toastLeftRightMargin @toastMarginProgress; + } + & .bar { + min-width: 0; + } + &.info .bar.bar.bar { + background: @toastInfoProgressColor; + } + &.warning .bar.bar.bar { + background: @toastWarningProgressColor; + } + &.success .bar.bar.bar { + background: @toastSuccessProgressColor; + } + &.error .bar.bar.bar { + background: @toastErrorProgressColor; + } + &.neutral .bar.bar.bar { + background: @toastNeutralProgressColor; + } + } + & > .ui.message when (@variationToastMessage) { + & > .close.icon when (@variationToastClose){ + top: @toastCloseTopDistance; + right: @toastCloseRightDistance; + } + & > .actions:last-child when (@variationToastActions) { + margin-bottom: @toastActionMargin; + } + &.icon when (@variationToastIcon) { + align-items: inherit; + & > :not(.icon):not(.actions) { + padding-left: @toastIconMessageContentPadding; + } + & > i.icon:not(.close) when (@variationToastIcon) { + display: inline-block; + position: absolute; + width: @toastIconMessageWidth; + top: 50%; + transform: translateY(-50%); + } + &:not(.vertical) { + &.actions > i.icon:not(.close) when (@variationToastActions) and (@variationToastIcon) { + top: e(%("calc(50%% - %d)", @toastIconCenteredAdjustment)); + transform: none; + } + &.icon.icon.icon when (@variationToastIcon){ + display: block; + } + } + } + } + & .ui.toast { + & > .close.icon when (@variationToastClose){ + cursor: pointer; + margin: 0; + opacity: @toastCloseOpacity; + transition: @toastCloseTransition; + &:hover { + opacity: 1; + } + } + &.vertical > .close.icon when (@variationToastVertical) and (@variationToastClose) { + margin-top: -@toastCloseTopDistance; + margin-right: -@toastCloseTopDistance; + } + &:not(.vertical) > .close.icon when (@variationToastClose) { + position: absolute; + top: @toastCloseTopDistance; + &:not(.left) { + right: @toastCloseRightDistance; + } + &.left { + margin-left: -@toastCloseRightDistance; + } + } + } + & .ui.card when (@variationToastCard) { + margin:0; + &.attached:not(.vertical) when (@variationToastAttached) { + &.bottom { + border-top-left-radius: 0; + border-top-right-radius: 0; + &.horizontal { + & > .image > img { + border-top-left-radius: 0; + } + & > .image:last-child > img { + border-top-right-radius: 0; + } + } + } + &.top { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + &.horizontal { + & > .image > img { + border-bottom-left-radius: 0; + } + & > .image:last-child > img { + border-bottom-right-radius: 0; + } + } + } + } + &.horizontal.actions when (@variationToastActions) { + & > .image > img { + border-bottom-left-radius: 0; + } + & > .image:last-child > img { + border-bottom-right-radius: 0; + } + } + } + & .progressing { + animation-iteration-count: 1; + animation-timing-function: linear; + & when (@variationToastProgress) { + &.up { + animation-name: progressUp; + } + &.down { + animation-name: progressDown; + } + } + &.wait { + animation-name: progressWait; + } + } + &:hover .pausable.progressing { + animation-play-state: paused; + } + & .ui.toast:not(.vertical) { + display:block; + } + & :not(.comment) { + &:not(.card) .actions when (@variationToastActions) { + margin: @toastActionMarginTop @toastActionMargin @toastActionMargin @toastActionMargin; + } + & .actions when (@variationToastActions) { + padding: @toastActionPadding @toastActionPadding @toastActionPaddingBottom @toastActionPadding; + text-align: right; + &.attached:not(.vertical) when (@variationToastAttached) { + margin-right: @toastLeftRightMargin; + } + &:not(.basic):not(.attached) { + background: @toastActionBackground; + border-top: @toastActionBorder; + } + &.left { + text-align: left; + } + } + } + & when (@variationToastVertical) { + & .vertical.actions > .button, + & > .vertical > .vertical.vertical, + & > .vertical.vertical.vertical { + display: flex; + } + } + & :not(.comment) .vertical.actions when (@variationToastVertical) and (@variationToastActions) { + flex-direction: column; + & > .button { + justify-content: center; + } + &.attached > .button when (@variationToastAttached) { + align-items: center; + } + &:not(.attached) { + border-top: 0; + margin-top: -@toastActionPaddingBottom; + margin-bottom: -@toastActionPaddingBottom; + margin-left: @toastActionMarginLeft; + justify-content: space-around; + &:not(.basic) { + border-left: @toastActionBorder; + } + & > .button:not(:last-child) { + margin-bottom: @toastActionMarginBottom; + } + &.top { + justify-content: flex-start; + } + &.bottom { + justify-content: flex-end; + } + } + } + } +} + +.ui.vertical.attached when (@variationToastVertical) and (@variationToastAttached) { + &:not(.left) { + &.card when (@variationToastCard) { + & > .image > img { + border-top-right-radius: 0; + } + &.horizontal > .image:last-child > img { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + } + &.card, + &.toast { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + &.actions when (@variationToastActions) { + border-top-right-radius: @toastBorderRadius; + border-bottom-right-radius: @toastBorderRadius; + & .button:first-child, + .button:last-child { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + } + &.message when (@variationToastMessage) { + border-top-right-radius: 0; + border-bottom-left-radius: @toastBorderRadius; + } + } + &.left { + &.card when (@variationToastCard) { + & > .image > img { + border-top-left-radius: 0; + } + &.horizontal > .image > img { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + } + &.card, + &.toast { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + &.actions when (@variationToastActions) { + border-top-left-radius: @toastBorderRadius; + border-bottom-left-radius: @toastBorderRadius; + & .button:first-child, + .button:last-child { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + & .button:not(:first-child):not(:last-child) { + margin-left: -@toastLeftRightMargin; + } + } + &.message.message.message when (@variationToastMessage) { + border-top-right-radius: @toastBorderRadius; + border-bottom-right-radius: @toastBorderRadius; + } + } +} + +.ui.attached:not(.vertical) when (@variationToastAttached) { + &:not(.top) { + &.actions when (@variationToastActions) { + border-bottom-left-radius: @toastBorderRadius; + border-bottom-right-radius: @toastBorderRadius; + & .button:first-child { + border-bottom-left-radius: @toastBorderRadius; + } + & .button:last-child { + border-bottom-right-radius: @toastBorderRadius; + } + } + } + &.top { + &.actions when (@variationToastActions) { + border-top-left-radius: @toastBorderRadius; + border-top-right-radius: @toastBorderRadius; + & .button:first-child { + border-top-left-radius: @toastBorderRadius; + } + & .button:last-child { + border-top-right-radius: @toastBorderRadius; + } + } + } +} + +/******************************* + Toast +*******************************/ + +.ui.toast { + display: none; + border-radius: @defaultBorderRadius; + padding: @toastPadding; + margin: @toastMargin; + color: @toastInvertedTextColor; + background-color: @toastNeutralColor; + & > .content > .header { + font-weight: bold; + color: inherit; + margin:0; + } + &.info when (@variationToastInfo) { + background-color: @toastInfoColor; + color: @toastTextColor; + } + &.warning when (@variationToastWarning) { + background-color: @toastWarningColor; + color: @toastTextColor; + } + &.success when (@variationToastSuccess) { + background-color: @toastSuccessColor; + color: @toastTextColor; + } + &.error when (@variationToastError) { + background-color: @toastErrorColor; + color: @toastTextColor; + } + &.neutral { + background-color: @toastNeutralColor; + color: @toastNeutralTextColor; + } + & > i.icon:not(.close) when (@variationToastIcon) { + font-size: @toastIconFontSize; + } + &:not(.vertical) { + & > i.icon:not(.close) when (@variationToastIcon) { + position: absolute; + & + .content { + padding-left: @toastIconContentPadding; + } + } + & > .close.icon + .content when (@variationToastClose){ + padding-left: @toastCloseDistance; + } + & > .ui.image when (@variationToastImage) { + position: absolute; + &.avatar + .content { + padding-left: @toastAvatarImageContentPadding; + min-height: @toastAvatarImageHeight; + } + &.mini + .content { + padding-left: @toastMiniImageContentPadding; + min-height: @toastMiniImageHeight; + } + &.tiny + .content { + padding-left: @toastTinyImageContentPadding; + min-height: @toastTinyImageHeight; + } + &.small + .content { + padding-left: @toastSmallImageContentPadding; + min-height: @toastSmallImageHeight; + } + } + & when (@variationToastImage) or (@variationToastIcon) { + & > .centered.image, + > .centered.icon { + transform: translateY(-50%); + top: 50%; + } + } + &.actions > .centered.image when (@variationToastActions) and (@variationToastImage) { + top: e(%("calc(50%% - %d)", @toastImageCenteredAdjustment)); + } + &.actions > .centered.icon when (@variationToastActions) and (@variationToastIcon) { + top: e(%("calc(50%% - %d)", @toastIconCenteredAdjustment)); + } + } + &.vertical when (@variationToastVertical) { + & > .close.icon + .content when (@variationToastClose){ + padding-left: @toastCloseDistanceVertical; + } + & when (@variationToastImage) or (@variationToastIcon) { + & > .ui.image + .content, + > i.icon:not(.close) + .content { + padding-left: @toastImageContentPadding; + } + } + & > .ui.image when (@variationToastImage){ + align-self: flex-start; + flex-shrink:0; /* IE11 fix */ + } + & when (@variationToastImage) or (@variationToastIcon) { + & > .centered.image, + > .centered.icon { + align-self: center; + } + } + } + + &.attached when (@variationToastAttached) { + &.bottom { + border-top-left-radius: 0; + border-top-right-radius: 0; + } + &.top { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } + } +} + + +.ui.hoverfloating.message:hover when (@variationToastMessage) and (@variationToastFloating) { + box-shadow: 0 0 0 1px inset, @floatingShadow; +} + +.ui.center.toast-container .toast-box, +.ui.right.toast-container .toast-box { + margin-left: auto; +} + +.ui.center.toast-container .toast-box { + margin-right: auto; +} + +/*-------------- + Colors +-------------- */ + +each(@colors, { + @color: replace(@key, '@', ''); + @c: @colors[@@color][color]; + @l: @colors[@@color][light]; + + .ui.@{color}.toast { + background-color: @c; + color: @toastTextColor; + } + & when (@variationToastInverted) { + .ui.inverted.@{color}.toast, + .ui.toast-container .toast-box > .inverted.@{color}.attached.progress .bar { + background-color: @l; + color: @toastInvertedTextColor; + } + } +}) + +& when (@variationToastInverted) { + .ui.inverted.toast { + color: @toastTextColor; + background-color: @toastInvertedColor; + } +} + +@media only screen and (max-width: @mobileToastBreakpoint) { + .ui.toast-container .toast-box { + &.toast-box, + & > .compact, + & > .vertical > *, + & > * { + width: auto; + max-width: 100%; + } + & > *:not(.vertical) { + min-width: @mobileWidth; + } + & when (@variationToastCard) { + & > .ui.card.horizontal, + > .vertical > .ui.horizontal.card { + min-width: initial; + } + } + } +} + +/*--------------- + Progress Bar + ----------------*/ +& when (@variationToastProgress) { + @keyframes progressDown { + 0% { + width: 100%; + } + 100% { + width: 0; + } + } + @keyframes progressUp { + 0% { + width: 0; + } + 100% { + width: 100%; + } + } +} +@keyframes progressWait { + 0% { + opacity: 1; + } + 100% { + opacity: 0; + } +} diff --git a/semantic/src/definitions/modules/transition.js b/semantic/src/definitions/modules/transition.js new file mode 100644 index 0000000..45dfefe --- /dev/null +++ b/semantic/src/definitions/modules/transition.js @@ -0,0 +1,1109 @@ +/*! + * # Fomantic-UI - Transition + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +'use strict'; + +$.isFunction = $.isFunction || function(obj) { + return typeof obj === "function" && typeof obj.nodeType !== "number"; +}; + +window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.fn.transition = function() { + var + $allModules = $(this), + moduleSelector = $allModules.selector || '', + + time = new Date().getTime(), + performance = [], + + moduleArguments = arguments, + query = moduleArguments[0], + queryArguments = [].slice.call(arguments, 1), + methodInvoked = (typeof query === 'string'), + + returnedValue + ; + $allModules + .each(function(index) { + var + $module = $(this), + element = this, + + // set at run time + settings, + instance, + + error, + className, + metadata, + animationEnd, + + moduleNamespace, + eventNamespace, + module + ; + + module = { + + initialize: function() { + + // get full settings + settings = module.get.settings.apply(element, moduleArguments); + + // shorthand + className = settings.className; + error = settings.error; + metadata = settings.metadata; + + // define namespace + eventNamespace = '.' + settings.namespace; + moduleNamespace = 'module-' + settings.namespace; + instance = $module.data(moduleNamespace) || module; + + // get vendor specific events + animationEnd = module.get.animationEndEvent(); + + if(methodInvoked) { + methodInvoked = module.invoke(query); + } + + // method not invoked, lets run an animation + if(methodInvoked === false) { + module.verbose('Converted arguments into settings object', settings); + if(settings.interval) { + module.delay(settings.animate); + } + else { + module.animate(); + } + module.instantiate(); + } + }, + + instantiate: function() { + module.verbose('Storing instance of module', module); + instance = module; + $module + .data(moduleNamespace, instance) + ; + }, + + destroy: function() { + module.verbose('Destroying previous module for', element); + $module + .removeData(moduleNamespace) + ; + }, + + refresh: function() { + module.verbose('Refreshing display type on next animation'); + delete module.displayType; + }, + + forceRepaint: function() { + module.verbose('Forcing element repaint'); + var + $parentElement = $module.parent(), + $nextElement = $module.next() + ; + if($nextElement.length === 0) { + $module.detach().appendTo($parentElement); + } + else { + $module.detach().insertBefore($nextElement); + } + }, + + repaint: function() { + module.verbose('Repainting element'); + var + fakeAssignment = element.offsetWidth + ; + }, + + delay: function(interval) { + var + direction = module.get.animationDirection(), + shouldReverse, + delay + ; + if(!direction) { + direction = module.can.transition() + ? module.get.direction() + : 'static' + ; + } + interval = (interval !== undefined) + ? interval + : settings.interval + ; + shouldReverse = (settings.reverse == 'auto' && direction == className.outward); + delay = (shouldReverse || settings.reverse == true) + ? ($allModules.length - index) * settings.interval + : index * settings.interval + ; + module.debug('Delaying animation by', delay); + setTimeout(module.animate, delay); + }, + + animate: function(overrideSettings) { + settings = overrideSettings || settings; + if(!module.is.supported()) { + module.error(error.support); + return false; + } + module.debug('Preparing animation', settings.animation); + if(module.is.animating()) { + if(settings.queue) { + if(!settings.allowRepeats && module.has.direction() && module.is.occurring() && module.queuing !== true) { + module.debug('Animation is currently occurring, preventing queueing same animation', settings.animation); + } + else { + module.queue(settings.animation); + } + return false; + } + else if(!settings.allowRepeats && module.is.occurring()) { + module.debug('Animation is already occurring, will not execute repeated animation', settings.animation); + return false; + } + else { + module.debug('New animation started, completing previous early', settings.animation); + instance.complete(); + } + } + if( module.can.animate() ) { + module.set.animating(settings.animation); + } + else { + module.error(error.noAnimation, settings.animation, element); + } + }, + + reset: function() { + module.debug('Resetting animation to beginning conditions'); + module.remove.animationCallbacks(); + module.restore.conditions(); + module.remove.animating(); + }, + + queue: function(animation) { + module.debug('Queueing animation of', animation); + module.queuing = true; + $module + .one(animationEnd + '.queue' + eventNamespace, function() { + module.queuing = false; + module.repaint(); + module.animate.apply(this, settings); + }) + ; + }, + + complete: function (event) { + if(event && event.target === element) { + event.stopPropagation(); + } + module.debug('Animation complete', settings.animation); + module.remove.completeCallback(); + module.remove.failSafe(); + if(!module.is.looping()) { + if( module.is.outward() ) { + module.verbose('Animation is outward, hiding element'); + module.restore.conditions(); + module.hide(); + } + else if( module.is.inward() ) { + module.verbose('Animation is outward, showing element'); + module.restore.conditions(); + module.show(); + } + else { + module.verbose('Static animation completed'); + module.restore.conditions(); + settings.onComplete.call(element); + } + } + }, + + force: { + visible: function() { + var + style = $module.attr('style'), + userStyle = module.get.userStyle(style), + displayType = module.get.displayType(), + overrideStyle = userStyle + 'display: ' + displayType + ' !important;', + inlineDisplay = $module[0].style.display, + mustStayHidden = !displayType || (inlineDisplay === 'none' && settings.skipInlineHidden) || $module[0].tagName.match(/(script|link|style)/i) + ; + if (mustStayHidden){ + module.remove.transition(); + return false; + } + module.verbose('Overriding default display to show element', displayType); + $module + .attr('style', overrideStyle) + ; + return true; + }, + hidden: function() { + var + style = $module.attr('style'), + currentDisplay = $module.css('display'), + emptyStyle = (style === undefined || style === '') + ; + if(currentDisplay !== 'none' && !module.is.hidden()) { + module.verbose('Overriding default display to hide element'); + $module + .css('display', 'none') + ; + } + else if(emptyStyle) { + $module + .removeAttr('style') + ; + } + } + }, + + has: { + direction: function(animation) { + var + hasDirection = false + ; + animation = animation || settings.animation; + if(typeof animation === 'string') { + animation = animation.split(' '); + $.each(animation, function(index, word){ + if(word === className.inward || word === className.outward) { + hasDirection = true; + } + }); + } + return hasDirection; + }, + inlineDisplay: function() { + var + style = $module.attr('style') || '' + ; + return Array.isArray(style.match(/display.*?;/, '')); + } + }, + + set: { + animating: function(animation) { + // remove previous callbacks + module.remove.completeCallback(); + + // determine exact animation + animation = animation || settings.animation; + var animationClass = module.get.animationClass(animation); + + // save animation class in cache to restore class names + module.save.animation(animationClass); + + if(module.force.visible()) { + module.remove.hidden(); + module.remove.direction(); + + module.start.animation(animationClass); + } + }, + duration: function(animationName, duration) { + duration = duration || settings.duration; + duration = (typeof duration == 'number') + ? duration + 'ms' + : duration + ; + if(duration || duration === 0) { + module.verbose('Setting animation duration', duration); + $module + .css({ + 'animation-duration': duration + }) + ; + } + }, + direction: function(direction) { + direction = direction || module.get.direction(); + if(direction == className.inward) { + module.set.inward(); + } + else { + module.set.outward(); + } + }, + looping: function() { + module.debug('Transition set to loop'); + $module + .addClass(className.looping) + ; + }, + hidden: function() { + $module + .addClass(className.transition) + .addClass(className.hidden) + ; + }, + inward: function() { + module.debug('Setting direction to inward'); + $module + .removeClass(className.outward) + .addClass(className.inward) + ; + }, + outward: function() { + module.debug('Setting direction to outward'); + $module + .removeClass(className.inward) + .addClass(className.outward) + ; + }, + visible: function() { + $module + .addClass(className.transition) + .addClass(className.visible) + ; + } + }, + + start: { + animation: function(animationClass) { + animationClass = animationClass || module.get.animationClass(); + module.debug('Starting tween', animationClass); + $module + .addClass(animationClass) + .one(animationEnd + '.complete' + eventNamespace, module.complete) + ; + if(settings.useFailSafe) { + module.add.failSafe(); + } + module.set.duration(settings.duration); + settings.onStart.call(element); + } + }, + + save: { + animation: function(animation) { + if(!module.cache) { + module.cache = {}; + } + module.cache.animation = animation; + }, + displayType: function(displayType) { + if(displayType !== 'none') { + $module.data(metadata.displayType, displayType); + } + }, + transitionExists: function(animation, exists) { + $.fn.transition.exists[animation] = exists; + module.verbose('Saving existence of transition', animation, exists); + } + }, + + restore: { + conditions: function() { + var + animation = module.get.currentAnimation() + ; + if(animation) { + $module + .removeClass(animation) + ; + module.verbose('Removing animation class', module.cache); + } + module.remove.duration(); + } + }, + + add: { + failSafe: function() { + var + duration = module.get.duration() + ; + module.timer = setTimeout(function() { + $module.triggerHandler(animationEnd); + }, duration + settings.failSafeDelay); + module.verbose('Adding fail safe timer', module.timer); + } + }, + + remove: { + animating: function() { + $module.removeClass(className.animating); + }, + animationCallbacks: function() { + module.remove.queueCallback(); + module.remove.completeCallback(); + }, + queueCallback: function() { + $module.off('.queue' + eventNamespace); + }, + completeCallback: function() { + $module.off('.complete' + eventNamespace); + }, + display: function() { + $module.css('display', ''); + }, + direction: function() { + $module + .removeClass(className.inward) + .removeClass(className.outward) + ; + }, + duration: function() { + $module + .css('animation-duration', '') + ; + }, + failSafe: function() { + module.verbose('Removing fail safe timer', module.timer); + if(module.timer) { + clearTimeout(module.timer); + } + }, + hidden: function() { + $module.removeClass(className.hidden); + }, + visible: function() { + $module.removeClass(className.visible); + }, + looping: function() { + module.debug('Transitions are no longer looping'); + if( module.is.looping() ) { + module.reset(); + $module + .removeClass(className.looping) + ; + } + }, + transition: function() { + $module + .removeClass(className.transition) + .removeClass(className.visible) + .removeClass(className.hidden) + ; + } + }, + get: { + settings: function(animation, duration, onComplete) { + // single settings object + if(typeof animation == 'object') { + return $.extend(true, {}, $.fn.transition.settings, animation); + } + // all arguments provided + else if(typeof onComplete == 'function') { + return $.extend({}, $.fn.transition.settings, { + animation : animation, + onComplete : onComplete, + duration : duration + }); + } + // only duration provided + else if(typeof duration == 'string' || typeof duration == 'number') { + return $.extend({}, $.fn.transition.settings, { + animation : animation, + duration : duration + }); + } + // duration is actually settings object + else if(typeof duration == 'object') { + return $.extend({}, $.fn.transition.settings, duration, { + animation : animation + }); + } + // duration is actually callback + else if(typeof duration == 'function') { + return $.extend({}, $.fn.transition.settings, { + animation : animation, + onComplete : duration + }); + } + // only animation provided + else { + return $.extend({}, $.fn.transition.settings, { + animation : animation + }); + } + }, + animationClass: function(animation) { + var + animationClass = animation || settings.animation, + directionClass = (module.can.transition() && !module.has.direction()) + ? module.get.direction() + ' ' + : '' + ; + return className.animating + ' ' + + className.transition + ' ' + + directionClass + + animationClass + ; + }, + currentAnimation: function() { + return (module.cache && module.cache.animation !== undefined) + ? module.cache.animation + : false + ; + }, + currentDirection: function() { + return module.is.inward() + ? className.inward + : className.outward + ; + }, + direction: function() { + return module.is.hidden() || !module.is.visible() + ? className.inward + : className.outward + ; + }, + animationDirection: function(animation) { + var + direction + ; + animation = animation || settings.animation; + if(typeof animation === 'string') { + animation = animation.split(' '); + // search animation name for out/in class + $.each(animation, function(index, word){ + if(word === className.inward) { + direction = className.inward; + } + else if(word === className.outward) { + direction = className.outward; + } + }); + } + // return found direction + if(direction) { + return direction; + } + return false; + }, + duration: function(duration) { + duration = duration || settings.duration; + if(duration === false) { + duration = $module.css('animation-duration') || 0; + } + return (typeof duration === 'string') + ? (duration.indexOf('ms') > -1) + ? parseFloat(duration) + : parseFloat(duration) * 1000 + : duration + ; + }, + displayType: function(shouldDetermine) { + shouldDetermine = (shouldDetermine !== undefined) + ? shouldDetermine + : true + ; + if(settings.displayType) { + return settings.displayType; + } + if(shouldDetermine && $module.data(metadata.displayType) === undefined) { + var currentDisplay = $module.css('display'); + if(currentDisplay === '' || currentDisplay === 'none'){ + // create fake element to determine display state + module.can.transition(true); + } else { + module.save.displayType(currentDisplay); + } + } + return $module.data(metadata.displayType); + }, + userStyle: function(style) { + style = style || $module.attr('style') || ''; + return style.replace(/display.*?;/, ''); + }, + transitionExists: function(animation) { + return $.fn.transition.exists[animation]; + }, + animationStartEvent: function() { + var + element = document.createElement('div'), + animations = { + 'animation' :'animationstart', + 'OAnimation' :'oAnimationStart', + 'MozAnimation' :'mozAnimationStart', + 'WebkitAnimation' :'webkitAnimationStart' + }, + animation + ; + for(animation in animations){ + if( element.style[animation] !== undefined ){ + return animations[animation]; + } + } + return false; + }, + animationEndEvent: function() { + var + element = document.createElement('div'), + animations = { + 'animation' :'animationend', + 'OAnimation' :'oAnimationEnd', + 'MozAnimation' :'mozAnimationEnd', + 'WebkitAnimation' :'webkitAnimationEnd' + }, + animation + ; + for(animation in animations){ + if( element.style[animation] !== undefined ){ + return animations[animation]; + } + } + return false; + } + + }, + + can: { + transition: function(forced) { + var + animation = settings.animation, + transitionExists = module.get.transitionExists(animation), + displayType = module.get.displayType(false), + elementClass, + tagName, + $clone, + currentAnimation, + inAnimation, + directionExists + ; + if( transitionExists === undefined || forced) { + module.verbose('Determining whether animation exists'); + elementClass = $module.attr('class'); + tagName = $module.prop('tagName'); + + $clone = $('<' + tagName + ' />').addClass( elementClass ).insertAfter($module); + currentAnimation = $clone + .addClass(animation) + .removeClass(className.inward) + .removeClass(className.outward) + .addClass(className.animating) + .addClass(className.transition) + .css('animationName') + ; + inAnimation = $clone + .addClass(className.inward) + .css('animationName') + ; + if(!displayType) { + displayType = $clone + .attr('class', elementClass) + .removeAttr('style') + .removeClass(className.hidden) + .removeClass(className.visible) + .show() + .css('display') + ; + module.verbose('Determining final display state', displayType); + module.save.displayType(displayType); + } + + $clone.remove(); + if(currentAnimation != inAnimation) { + module.debug('Direction exists for animation', animation); + directionExists = true; + } + else if(currentAnimation == 'none' || !currentAnimation) { + module.debug('No animation defined in css', animation); + return; + } + else { + module.debug('Static animation found', animation, displayType); + directionExists = false; + } + module.save.transitionExists(animation, directionExists); + } + return (transitionExists !== undefined) + ? transitionExists + : directionExists + ; + }, + animate: function() { + // can transition does not return a value if animation does not exist + return (module.can.transition() !== undefined); + } + }, + + is: { + animating: function() { + return $module.hasClass(className.animating); + }, + inward: function() { + return $module.hasClass(className.inward); + }, + outward: function() { + return $module.hasClass(className.outward); + }, + looping: function() { + return $module.hasClass(className.looping); + }, + occurring: function(animation) { + animation = animation || settings.animation; + animation = '.' + animation.replace(' ', '.'); + return ( $module.filter(animation).length > 0 ); + }, + visible: function() { + return $module.is(':visible'); + }, + hidden: function() { + return $module.css('visibility') === 'hidden'; + }, + supported: function() { + return(animationEnd !== false); + } + }, + + hide: function() { + module.verbose('Hiding element'); + if( module.is.animating() ) { + module.reset(); + } + element.blur(); // IE will trigger focus change if element is not blurred before hiding + module.remove.display(); + module.remove.visible(); + if($.isFunction(settings.onBeforeHide)){ + settings.onBeforeHide.call(element,function(){ + module.hideNow(); + }); + } else { + module.hideNow(); + } + + }, + + hideNow: function() { + module.set.hidden(); + module.force.hidden(); + settings.onHide.call(element); + settings.onComplete.call(element); + // module.repaint(); + }, + + show: function(display) { + module.verbose('Showing element', display); + if(module.force.visible()) { + module.remove.hidden(); + module.set.visible(); + settings.onShow.call(element); + settings.onComplete.call(element); + // module.repaint(); + } + }, + + toggle: function() { + if( module.is.visible() ) { + module.hide(); + } + else { + module.show(); + } + }, + + stop: function() { + module.debug('Stopping current animation'); + $module.triggerHandler(animationEnd); + }, + + stopAll: function() { + module.debug('Stopping all animation'); + module.remove.queueCallback(); + $module.triggerHandler(animationEnd); + }, + + clear: { + queue: function() { + module.debug('Clearing animation queue'); + module.remove.queueCallback(); + } + }, + + enable: function() { + module.verbose('Starting animation'); + $module.removeClass(className.disabled); + }, + + disable: function() { + module.debug('Stopping animation'); + $module.addClass(className.disabled); + }, + + 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($allModules.length > 1) { + title += ' ' + '(' + $allModules.length + ')'; + } + 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 = []; + } + }, + // modified for transition to return invoke success + 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 { + return false; + } + }); + } + if ( $.isFunction( found ) ) { + response = found.apply(context, passedArguments); + } + else if(found !== undefined) { + response = found; + } + + if(Array.isArray(returnedValue)) { + returnedValue.push(response); + } + else if(returnedValue !== undefined) { + returnedValue = [returnedValue, response]; + } + else if(response !== undefined) { + returnedValue = response; + } + return (found !== undefined) + ? found + : false + ; + } + }; + module.initialize(); + }) + ; + return (returnedValue !== undefined) + ? returnedValue + : this + ; +}; + +// Records if CSS transition is available +$.fn.transition.exists = {}; + +$.fn.transition.settings = { + + // module info + name : 'Transition', + + // hide all output from this component regardless of other settings + silent : false, + + // debug content outputted to console + debug : false, + + // verbose debug output + verbose : false, + + // performance data output + performance : true, + + // event namespace + namespace : 'transition', + + // delay between animations in group + interval : 0, + + // whether group animations should be reversed + reverse : 'auto', + + // animation callback event + onStart : function() {}, + onComplete : function() {}, + onShow : function() {}, + onHide : function() {}, + + // whether timeout should be used to ensure callback fires in cases animationend does not + useFailSafe : true, + + // delay in ms for fail safe + failSafeDelay : 100, + + // whether EXACT animation can occur twice in a row + allowRepeats : false, + + // Override final display type on visible + displayType : false, + + // animation duration + animation : 'fade', + duration : false, + + // new animations will occur after previous ones + queue : true, + +// whether initially inline hidden objects should be skipped for transition + skipInlineHidden: false, + + metadata : { + displayType: 'display' + }, + + className : { + animating : 'animating', + disabled : 'disabled', + hidden : 'hidden', + inward : 'in', + loading : 'loading', + looping : 'looping', + outward : 'out', + transition : 'transition', + visible : 'visible' + }, + + // possible errors + error: { + noAnimation : 'Element is no longer attached to DOM. Unable to animate. Use silent setting to surpress this warning in production.', + repeated : 'That animation is already occurring, cancelling repeated animation', + method : 'The method you called is not defined', + support : 'This browser does not support CSS animations' + } + +}; + + +})( jQuery, window, document ); diff --git a/semantic/src/definitions/modules/transition.less b/semantic/src/definitions/modules/transition.less new file mode 100644 index 0000000..2990d53 --- /dev/null +++ b/semantic/src/definitions/modules/transition.less @@ -0,0 +1,82 @@ +/*! + * # Fomantic-UI - Transition + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + + +/******************************* + Theme +*******************************/ + +@type : 'module'; +@element : 'transition'; + +@import (multiple) '../../theme.config'; + +/******************************* + Transitions +*******************************/ + +.transition { + animation-iteration-count: 1; + animation-duration: @transitionDefaultDuration; + animation-timing-function: @transitionDefaultEasing; + animation-fill-mode: @transitionDefaultFill; +} + +/******************************* + States +*******************************/ + + +/* Animating */ +.animating.transition { + backface-visibility: @backfaceVisibility; + visibility: visible !important; +} + +& when (@variationTransitionLoading) { + /* Loading */ + .loading.transition { + position: absolute; + top: -99999px; + left: -99999px; + } +} + +/* Hidden */ +.hidden.transition { + display: none; + visibility: hidden; +} + +/* Visible */ +.visible.transition { + display: block !important; + visibility: visible !important; +/* backface-visibility: @backfaceVisibility; + transform: @use3DAcceleration;*/ +} + +& when (@variationTransitionDisabled) { + /* Disabled */ + .disabled.transition { + animation-play-state: paused; + } +} + +/******************************* + Variations +*******************************/ +& when (@variationTransitionLoading) { + .looping.transition { + animation-iteration-count: infinite; + } +} + +.loadUIOverrides(); diff --git a/semantic/src/definitions/views/ad.less b/semantic/src/definitions/views/ad.less new file mode 100644 index 0000000..8d10cb1 --- /dev/null +++ b/semantic/src/definitions/views/ad.less @@ -0,0 +1,297 @@ +/*! + * # Fomantic-UI - Ad + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Copyright 2013 Contributors + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +/******************************* + Theme +*******************************/ + +@type : 'view'; +@element : 'ad'; + +@import (multiple) '../../theme.config'; + +/******************************* + Advertisement +*******************************/ + +.ui.ad { + display: block; + overflow: @overflow; + margin: @margin; +} + +.ui.ad:first-child { + margin: 0; +} + +.ui.ad:last-child { + margin: 0; +} + +.ui.ad iframe { + margin: 0; + padding: 0; + border: none; + overflow: hidden; +} + +/*-------------- + Common +---------------*/ +& when (@variationAdLeaderboard) { + /* Leaderboard */ + .ui.leaderboard.ad { + width: 728px; + height: 90px; + } +} + +& when (@variationAdRectangle) { + /* Medium Rectangle */ + .ui[class*="medium rectangle"].ad { + width: 300px; + height: 250px; + } + + /* Large Rectangle */ + .ui[class*="large rectangle"].ad { + width: 336px; + height: 280px; + } + /* Half Page */ + .ui[class*="half page"].ad { + width: 300px; + height: 600px; + } +} + +& when (@variationAdSquare) { + /*-------------- + Square + ---------------*/ + + /* Square */ + .ui.square.ad { + width: 250px; + height: 250px; + } + + /* Small Square */ + .ui[class*="small square"].ad { + width: 200px; + height: 200px; + } +} + +& when (@variationAdRectangle) { + /*-------------- + Rectangle + ---------------*/ + + /* Small Rectangle */ + .ui[class*="small rectangle"].ad { + width: 180px; + height: 150px; + } + + /* Vertical Rectangle */ + .ui[class*="vertical rectangle"].ad { + width: 240px; + height: 400px; + } +} + +& when (@variationAdButton) { + /*-------------- + Button + ---------------*/ + + .ui.button.ad { + width: 120px; + height: 90px; + } + & when (@variationAdSquare) { + .ui[class*="square button"].ad { + width: 125px; + height: 125px; + } + } + .ui[class*="small button"].ad { + width: 120px; + height: 60px; + } +} + +& when (@variationAdSkyscraper) { + /*-------------- + Skyscrapers + ---------------*/ + + /* Skyscraper */ + .ui.skyscraper.ad { + width: 120px; + height: 600px; + } + + /* Wide Skyscraper */ + .ui[class*="wide skyscraper"].ad { + width: 160px; + } +} + +& when (@variationAdBanner) { + /*-------------- + Banners + ---------------*/ + + /* Banner */ + .ui.banner.ad { + width: 468px; + height: 60px; + } + + /* Vertical Banner */ + .ui[class*="vertical banner"].ad { + width: 120px; + height: 240px; + } + + /* Top Banner */ + .ui[class*="top banner"].ad { + width: 930px; + height: 180px; + } + + /* Half Banner */ + .ui[class*="half banner"].ad { + width: 234px; + height: 60px; + } +} + +/*-------------- + Boards +---------------*/ +& when (@variationAdLeaderboard) { + /* Leaderboard */ + .ui[class*="large leaderboard"].ad { + width: 970px; + height: 90px; + } +} + +& when (@variationAdBillboard) { + /* Billboard */ + .ui.billboard.ad { + width: 970px; + height: 250px; + } +} + +& when (@variationAdPanorama) { + /*-------------- + Panorama + ---------------*/ + + /* Panorama */ + .ui.panorama.ad { + width: 980px; + height: 120px; + } +} + +& when (@variationAdNetboard) { + /*-------------- + Netboard + ---------------*/ + + /* Netboard */ + .ui.netboard.ad { + width: 580px; + height: 400px; + } +} + +& when (@variationAdMobile) { + /*-------------- + Mobile + ---------------*/ + & when (@variationAdBanner) { + /* Large Mobile Banner */ + .ui[class*="large mobile banner"].ad { + width: 320px; + height: 100px; + } + } + & when (@variationAdLeaderboard) { + /* Mobile Leaderboard */ + .ui[class*="mobile leaderboard"].ad { + width: 320px; + height: 50px; + } + } + +/******************************* + Types +*******************************/ + + /* Mobile Sizes */ + .ui.mobile.ad { + display: none; + } + + @media only screen and (max-width : @largestMobileScreen) { + .ui.mobile.ad { + display: block; + } + } +} + + +/******************************* + Variations +*******************************/ + +& when (@variationAdCentered) { + .ui.centered.ad { + margin-left: auto; + margin-right: auto; + } +} +& when (@variationAdTest) { + .ui.test.ad { + position: relative; + background: @testBackground; + } + .ui.test.ad:after { + position: absolute; + top: 50%; + left: 50%; + width: 100%; + text-align: center; + transform: translateX(-50%) translateY(-50%); + + content: @testText; + color: @testColor; + font-size: @testFontSize; + font-weight: @testFontWeight; + } + & when (@variationAdMobile) { + .ui.mobile.test.ad:after { + font-size: @testMobileFontSize; + } + } + .ui.test.ad[data-text]:after { + content: attr(data-text); + } +} + +.loadUIOverrides(); diff --git a/semantic/src/definitions/views/card.less b/semantic/src/definitions/views/card.less new file mode 100644 index 0000000..fba8aee --- /dev/null +++ b/semantic/src/definitions/views/card.less @@ -0,0 +1,978 @@ +/*! + * # Fomantic-UI - Card + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +/******************************* + Theme +*******************************/ + +@type : 'view'; +@element : 'card'; + +@import (multiple) '../../theme.config'; + +/******************************* + Standard +*******************************/ + +/*-------------- + Card +---------------*/ + +.ui.cards > .card, +.ui.card { + max-width: 100%; + position: relative; + display: @display; + flex-direction: column; + + width: @width; + min-height: @minHeight; + background: @background; + padding: @padding; + + border: @border; + border-radius: @borderRadius; + box-shadow: @boxShadow; + transition: @transition; + z-index: @zIndex; + word-wrap: break-word; +} +.ui.card { + margin: @margin; +} + +.ui.cards > .card a, +.ui.card a { + cursor: pointer; +} + +.ui.card:first-child { + margin-top: 0; +} +.ui.card:last-child { + margin-bottom: 0; +} + +/*-------------- + Cards +---------------*/ + +.ui.cards { + display: @groupDisplay; + margin: @groupMargin; + flex-wrap: wrap; +} + +.ui.cards > .card { + display: @groupCardDisplay; + margin: @groupCardMargin; + float: @groupCardFloat; +} + +/* Clearing */ +.ui.cards:after, +.ui.card:after { + display: block; + content: ' '; + height: 0; + clear: both; + overflow: hidden; + visibility: hidden; +} + + +/* Consecutive Card Groups Preserve Row Spacing */ +.ui.cards ~ .ui.cards { + margin-top: @consecutiveGroupDistance; +} + + +/*-------------- + Rounded Edges +---------------*/ + +.ui.cards > .card > :first-child, +.ui.card > :first-child { + border-radius: @borderRadius @borderRadius 0 0 !important; + border-top: none !important; +} + +.ui.cards > .card > :last-child, +.ui.card > :last-child { + border-radius: 0 0 @borderRadius @borderRadius !important; +} + +.ui.cards > .card > :only-child, +.ui.card > :only-child { + border-radius: @borderRadius !important; +} + +/*-------------- + Images +---------------*/ + +.ui.cards > .card > .image, +.ui.card > .image { + position: relative; + display: block; + flex: 0 0 auto; + padding: @imagePadding; + background: @imageBackground; +} +.ui.cards > .card > .image > img, +.ui.card > .image > img { + display: block; + width: 100%; + height: auto; + border-radius: inherit; +} +.ui.cards > .card > .image:not(.ui) > img, +.ui.card > .image:not(.ui) > img { + border: @imageBorder; +} + +/*-------------- + Content +---------------*/ + +.ui.cards > .card > .content, +.ui.card > .content { + flex-grow: 1; + border: @contentBorder; + border-top: @contentDivider; + background: @contentBackground; + margin: @contentMargin; + padding: @contentPadding; + box-shadow: @contentBoxShadow; + font-size: @contentFontSize; + border-radius: @contentBorderRadius; +} + +.ui.cards > .card > .content:after, +.ui.card > .content:after { + display: block; + content: ' '; + height: 0; + clear: both; + overflow: hidden; + visibility: hidden; +} + +.ui.cards > .card > .content > .header, +.ui.card > .content > .header { + display: block; + margin: @headerMargin; + font-family: @headerFont; + color: @headerColor; +} + +/* Default Header Size */ +.ui.cards > .card > .content > .header:not(.ui), +.ui.card > .content > .header:not(.ui) { + font-weight: @headerFontWeight; + font-size: @headerFontSize; + margin-top: @headerLineHeightOffset; + line-height: @headerLineHeight; +} + +.ui.cards > .card > .content > .meta + .description, +.ui.cards > .card > .content > .header + .description, +.ui.card > .content > .meta + .description, +.ui.card > .content > .header + .description { + margin-top: @descriptionDistance; +} + +/*---------------- + Floated Content +-----------------*/ + +.ui.cards > .card [class*="left floated"], +.ui.card [class*="left floated"] { + float: left; +} +.ui.cards > .card [class*="right floated"], +.ui.card [class*="right floated"] { + float: right; +} + +/*-------------- + Aligned +---------------*/ + +.ui.cards > .card [class*="left aligned"], +.ui.card [class*="left aligned"] { + text-align: left; +} +.ui.cards > .card [class*="center aligned"], +.ui.card [class*="center aligned"] { + text-align: center; +} +.ui.cards > .card [class*="right aligned"], +.ui.card [class*="right aligned"] { + text-align: right; +} + + +/*-------------- + Content Image +---------------*/ + +.ui.cards > .card .content img, +.ui.card .content img { + display: inline-block; + vertical-align: @contentImageVerticalAlign; + width: @contentImageWidth; +} +.ui.cards > .card img.avatar, +.ui.cards > .card .avatar img, +.ui.card img.avatar, +.ui.card .avatar img { + width: @avatarSize; + height: @avatarSize; + border-radius: @avatarBorderRadius; +} + + +/*-------------- + Description +---------------*/ + +.ui.cards > .card > .content > .description, +.ui.card > .content > .description { + clear: both; + color: @descriptionColor; +} + +/*-------------- + Paragraph +---------------*/ + +.ui.cards > .card > .content p, +.ui.card > .content p { + margin: 0 0 @paragraphDistance; +} +.ui.cards > .card > .content p:last-child, +.ui.card > .content p:last-child { + margin-bottom: 0; +} + +/*-------------- + Meta +---------------*/ + +.ui.cards > .card .meta, +.ui.card .meta { + font-size: @metaFontSize; + color: @metaColor; +} +.ui.cards > .card .meta *, +.ui.card .meta * { + margin-right: @metaSpacing; +} +.ui.cards > .card .meta :last-child, +.ui.card .meta :last-child { + margin-right: 0; +} + +.ui.cards > .card .meta [class*="right floated"], +.ui.card .meta [class*="right floated"] { + margin-right: 0; + margin-left: @metaSpacing; +} + +/*-------------- + Links +---------------*/ + +/* Generic */ +.ui.cards > .card > .content a:not(.ui), +.ui.card > .content a:not(.ui) { + color: @contentLinkColor; + transition: @contentLinkTransition; +} +.ui.cards > .card > .content a:not(.ui):hover, +.ui.card > .content a:not(.ui):hover { + color: @contentLinkHoverColor; +} + +/* Header */ +.ui.cards > .card > .content > a.header, +.ui.card > .content > a.header { + color: @headerLinkColor; +} +.ui.cards > .card > .content > a.header:hover, +.ui.card > .content > a.header:hover { + color: @headerLinkHoverColor; +} + +/* Meta */ +.ui.cards > .card .meta > a:not(.ui), +.ui.card .meta > a:not(.ui) { + color: @metaLinkColor; +} +.ui.cards > .card .meta > a:not(.ui):hover, +.ui.card .meta > a:not(.ui):hover { + color: @metaLinkHoverColor; +} + +/*-------------- + Buttons +---------------*/ + +.ui.cards > .card > .buttons, +.ui.card > .buttons, +.ui.cards > .card > .button, +.ui.card > .button { + margin: @buttonMargin; + width: @buttonWidth; + &:last-child { + margin-bottom: -@borderWidth; + } +} + +/*-------------- + Dimmer +---------------*/ + +.ui.cards > .card .dimmer, +.ui.card .dimmer { + background: @dimmerColor; + z-index: @dimmerZIndex; +} + +/*-------------- + Labels +---------------*/ + +/*-----Star----- */ + +/* Icon */ +.ui.cards > .card > .content .star.icon, +.ui.card > .content .star.icon { + cursor: pointer; + opacity: @actionOpacity; + transition: @actionTransition; +} +.ui.cards > .card > .content .star.icon:hover, +.ui.card > .content .star.icon:hover { + opacity: @actionHoverOpacity; + color: @starColor; +} +.ui.cards > .card > .content .active.star.icon, +.ui.card > .content .active.star.icon { + color: @starActiveColor; +} + +/*-----Like----- */ + +/* Icon */ +.ui.cards > .card > .content .like.icon, +.ui.card > .content .like.icon { + cursor: pointer; + opacity: @actionOpacity; + transition: @actionTransition; +} +.ui.cards > .card > .content .like.icon:hover, +.ui.card > .content .like.icon:hover { + opacity: @actionHoverOpacity; + color: @likeColor; +} +.ui.cards > .card > .content .active.like.icon, +.ui.card > .content .active.like.icon { + color: @likeActiveColor; +} + +/*---------------- + Extra Content +-----------------*/ + +.ui.cards > .card > .extra, +.ui.card > .extra { + max-width: 100%; + min-height: 0 !important; + flex-grow: 0; + border-top: @extraDivider !important; + position: @extraPosition; + background: @extraBackground; + width: @extraWidth; + margin: @extraMargin; + padding: @extraPadding; + top: @extraTop; + left: @extraLeft; + color: @extraColor; + box-shadow: @extraBoxShadow; + transition: @extraTransition; +} +.ui.cards > .card > .extra a:not(.ui), +.ui.card > .extra a:not(.ui) { + color: @extraLinkColor; +} +.ui.cards > .card > .extra a:not(.ui):hover, +.ui.card > .extra a:not(.ui):hover { + color: @extraLinkHoverColor; +} + + +/******************************* + Variations +*******************************/ + +& when (@variationCardHorizontal) { + /*------------------- + Horizontal + --------------------*/ + + .ui.horizontal.cards > .card, + .ui.card.horizontal { + flex-direction: row; + flex-wrap: wrap; + min-width: @horizontalMinWidth; + width: @horizontalWidth; + max-width: 100%; + } + + .ui.horizontal.cards > .card > .image, + .ui.card.horizontal > .image { + border-radius: @defaultBorderRadius 0 0 @defaultBorderRadius; + width: @horizontalImageWidth; + } + + .ui.horizontal.cards > .card > .image > img, + .ui.card.horizontal > .image > img { + background-size: cover; + background-repeat: no-repeat; + background-position: center; + justify-content: center; + align-items: center; + display: -webkit-box; + display: -moz-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + width: 100%; + height: 100%; + border-radius: @defaultBorderRadius 0 0 @defaultBorderRadius; + } + .ui.horizontal.cards > .card > .image:last-child > img, + .ui.card.horizontal > .image:last-child > img { + border-radius: 0 @defaultBorderRadius @defaultBorderRadius 0; + } + .ui.horizontal.cards > .card > .content, .ui.horizontal.card > .content { + flex-basis: 1px; + } + .ui.horizontal.cards > .card > .extra, .ui.horizontal.card > .extra { + flex-basis: 100%; + } +} + +& when (@variationCardRaised) { + /*------------------- + Raised + --------------------*/ + + .ui.raised.cards > .card, + .ui.raised.card { + box-shadow: @raisedShadow; + } + & when (@variationCardLink) { + .ui.raised.cards a.card:hover, + .ui.link.cards .raised.card:hover, + a.ui.raised.card:hover, + .ui.link.raised.card:hover { + box-shadow: @raisedShadowHover; + } + } +} + +& when (@variationCardCentered) { + /*------------------- + Centered + --------------------*/ + + .ui.centered.cards { + justify-content: center; + } + .ui.centered.card { + margin-left: auto; + margin-right: auto; + } +} + +& when (@variationCardFluid) { + /*------------------- + Fluid + --------------------*/ + + .ui.fluid.card { + width: 100%; + max-width: 9999px; + } +} + +& when (@variationCardLink) { + /*------------------- + Link + --------------------*/ + + .ui.cards a.card, + .ui.link.cards .card, + a.ui.card, + .ui.link.card { + transform: none; + } + + + .ui.cards a.card:hover, + .ui.link.cards .card:not(.icon):hover, + a.ui.card:hover, + .ui.link.card:hover { + cursor: pointer; + z-index: @linkHoverZIndex; + background: @linkHoverBackground; + border: @linkHoverBorder; + box-shadow: @linkHoverBoxShadow; + transform: @linkHoverTransform; + } +} + +/*------------------- + Colors +--------------------*/ + +each(@colors,{ + @color: replace(@key,'@',''); + @c: @colors[@@color][color]; + @h: @colors[@@color][hover]; + @l: @colors[@@color][light]; + @lh: @colors[@@color][lightHover]; + + .ui.@{color}.cards > .card, + .ui.cards > .@{color}.card, + .ui.@{color}.card { + box-shadow: + @borderShadow, + 0 @coloredShadowDistance 0 0 @c, + @shadowBoxShadow + ; + &:hover { + box-shadow: + @borderShadow, + 0 @coloredShadowDistance 0 0 @h, + @shadowHoverBoxShadow + ; + } + } + & when (@variationCardInverted) { + .ui.inverted.@{color}.cards > .card, + .ui.inverted.cards > .@{color}.card, + .ui.inverted.@{color}.card { + box-shadow: + 0 @shadowDistance 3px 0 @solidWhiteBorderColor, + 0 @coloredShadowDistance 0 0 @l, + 0 0 0 @borderWidth @solidWhiteBorderColor + ; + &:hover { + box-shadow: + 0 @shadowDistance 3px 0 @solidWhiteBorderColor, + 0 @coloredShadowDistance 0 0 @lh, + 0 0 0 @borderWidth @solidWhiteBorderColor + ; + } + } + } +}) + +/*-------------- + Card Count +---------------*/ + +.ui.one.cards { + margin-left: @oneCardOffset; + margin-right: @oneCardOffset; +} +.ui.one.cards > .card { + width: @oneCard; +} + +.ui.two.cards { + margin-left: @twoCardOffset; + margin-right: @twoCardOffset; +} +.ui.two.cards > .card { + width: @twoCard; + margin-left: @twoCardSpacing; + margin-right: @twoCardSpacing; +} + +.ui.three.cards { + margin-left: @threeCardOffset; + margin-right: @threeCardOffset; +} +.ui.three.cards > .card { + width: @threeCard; + margin-left: @threeCardSpacing; + margin-right: @threeCardSpacing; +} + +.ui.four.cards { + margin-left: @fourCardOffset; + margin-right: @fourCardOffset; +} +.ui.four.cards > .card { + width: @fourCard; + margin-left: @fourCardSpacing; + margin-right: @fourCardSpacing; +} + +.ui.five.cards { + margin-left: @fiveCardOffset; + margin-right: @fiveCardOffset; +} +.ui.five.cards > .card { + width: @fiveCard; + margin-left: @fiveCardSpacing; + margin-right: @fiveCardSpacing; +} + +.ui.six.cards { + margin-left: @sixCardOffset; + margin-right: @sixCardOffset; +} +.ui.six.cards > .card { + width: @sixCard; + margin-left: @sixCardSpacing; + margin-right: @sixCardSpacing; +} + +.ui.seven.cards { + margin-left: @sevenCardOffset; + margin-right: @sevenCardOffset; +} +.ui.seven.cards > .card { + width: @sevenCard; + margin-left: @sevenCardSpacing; + margin-right: @sevenCardSpacing; +} + +.ui.eight.cards { + margin-left: @eightCardOffset; + margin-right: @eightCardOffset; +} +.ui.eight.cards > .card { + width: @eightCard; + margin-left: @eightCardSpacing; + margin-right: @eightCardSpacing; + font-size: 11px; +} + +.ui.nine.cards { + margin-left: @nineCardOffset; + margin-right: @nineCardOffset; +} +.ui.nine.cards > .card { + width: @nineCard; + margin-left: @nineCardSpacing; + margin-right: @nineCardSpacing; + font-size: 10px; +} + +.ui.ten.cards { + margin-left: @tenCardOffset; + margin-right: @tenCardOffset; +} +.ui.ten.cards > .card { + width: @tenCard; + margin-left: @tenCardSpacing; + margin-right: @tenCardSpacing; +} + +& when (@variationCardDoubling) { + /*------------------- + Doubling + --------------------*/ + + /* Mobile Only */ + @media only screen and (max-width : @largestMobileScreen) { + .ui.two.doubling.cards { + margin-left: @oneCardOffset; + margin-right: @oneCardOffset; + } + .ui.two.doubling.cards > .card { + width: @oneCard; + margin-left: @oneCardSpacing; + margin-right: @oneCardSpacing; + } + .ui.three.doubling.cards { + margin-left: @twoCardOffset; + margin-right: @twoCardOffset; + } + .ui.three.doubling.cards > .card { + width: @twoCard; + margin-left: @twoCardSpacing; + margin-right: @twoCardSpacing; + } + .ui.four.doubling.cards { + margin-left: @twoCardOffset; + margin-right: @twoCardOffset; + } + .ui.four.doubling.cards > .card { + width: @twoCard; + margin-left: @twoCardSpacing; + margin-right: @twoCardSpacing; + } + .ui.five.doubling.cards { + margin-left: @twoCardOffset; + margin-right: @twoCardOffset; + } + .ui.five.doubling.cards > .card { + width: @twoCard; + margin-left: @twoCardSpacing; + margin-right: @twoCardSpacing; + } + .ui.six.doubling.cards { + margin-left: @twoCardOffset; + margin-right: @twoCardOffset; + } + .ui.six.doubling.cards > .card { + width: @twoCard; + margin-left: @twoCardSpacing; + margin-right: @twoCardSpacing; + } + .ui.seven.doubling.cards { + margin-left: @threeCardOffset; + margin-right: @threeCardOffset; + } + .ui.seven.doubling.cards > .card { + width: @threeCard; + margin-left: @threeCardSpacing; + margin-right: @threeCardSpacing; + } + .ui.eight.doubling.cards { + margin-left: @threeCardOffset; + margin-right: @threeCardOffset; + } + .ui.eight.doubling.cards > .card { + width: @threeCard; + margin-left: @threeCardSpacing; + margin-right: @threeCardSpacing; + } + .ui.nine.doubling.cards { + margin-left: @threeCardOffset; + margin-right: @threeCardOffset; + } + .ui.nine.doubling.cards > .card { + width: @threeCard; + margin-left: @threeCardSpacing; + margin-right: @threeCardSpacing; + } + .ui.ten.doubling.cards { + margin-left: @threeCardOffset; + margin-right: @threeCardOffset; + } + .ui.ten.doubling.cards > .card { + width: @threeCard; + margin-left: @threeCardSpacing; + margin-right: @threeCardSpacing; + } + } + + /* Tablet Only */ + @media only screen and (min-width : @tabletBreakpoint) and (max-width : @largestTabletScreen) { + .ui.two.doubling.cards { + margin-left: @oneCardOffset; + margin-right: @oneCardOffset; + } + .ui.two.doubling.cards > .card { + width: @oneCard; + margin-left: @oneCardSpacing; + margin-right: @oneCardSpacing; + } + .ui.three.doubling.cards { + margin-left: @twoCardOffset; + margin-right: @twoCardOffset; + } + .ui.three.doubling.cards > .card { + width: @twoCard; + margin-left: @twoCardSpacing; + margin-right: @twoCardSpacing; + } + .ui.four.doubling.cards { + margin-left: @twoCardOffset; + margin-right: @twoCardOffset; + } + .ui.four.doubling.cards > .card { + width: @twoCard; + margin-left: @twoCardSpacing; + margin-right: @twoCardSpacing; + } + .ui.five.doubling.cards { + margin-left: @threeCardOffset; + margin-right: @threeCardOffset; + } + .ui.five.doubling.cards > .card { + width: @threeCard; + margin-left: @threeCardSpacing; + margin-right: @threeCardSpacing; + } + .ui.six.doubling.cards { + margin-left: @threeCardOffset; + margin-right: @threeCardOffset; + } + .ui.six.doubling.cards > .card { + width: @threeCard; + margin-left: @threeCardSpacing; + margin-right: @threeCardSpacing; + } + .ui.eight.doubling.cards { + margin-left: @threeCardOffset; + margin-right: @threeCardOffset; + } + .ui.eight.doubling.cards > .card { + width: @threeCard; + margin-left: @threeCardSpacing; + margin-right: @threeCardSpacing; + } + .ui.eight.doubling.cards { + margin-left: @fourCardOffset; + margin-right: @fourCardOffset; + } + .ui.eight.doubling.cards > .card { + width: @fourCard; + margin-left: @fourCardSpacing; + margin-right: @fourCardSpacing; + } + .ui.nine.doubling.cards { + margin-left: @fourCardOffset; + margin-right: @fourCardOffset; + } + .ui.nine.doubling.cards > .card { + width: @fourCard; + margin-left: @fourCardSpacing; + margin-right: @fourCardSpacing; + } + .ui.ten.doubling.cards { + margin-left: @fiveCardOffset; + margin-right: @fiveCardOffset; + } + .ui.ten.doubling.cards > .card { + width: @fiveCard; + margin-left: @fiveCardSpacing; + margin-right: @fiveCardSpacing; + } + } +} + +& when (@variationCardStackable) { + /*------------------- + Stackable + --------------------*/ + + @media only screen and (max-width : @largestMobileScreen) { + .ui.stackable.cards { + display: block !important; + } + .ui.stackable.cards .card:first-child { + margin-top: 0 !important; + } + .ui.stackable.cards > .card { + display: block !important; + height: auto !important; + margin: @stackableRowSpacing @stackableCardSpacing; + padding: 0 !important; + width: @stackableMargin !important; + } + } +} + +/*-------------- + Size +---------------*/ + +.ui.cards > .card { + font-size: @medium; +} +& when not (@variationCardSizes = false) { + each(@variationCardSizes, { + @s: @@value; + .ui.@{value}.cards .card { + font-size: @s; + } + }) +} + +& when (@variationCardInverted) { + /*----------------- + Inverted + ------------------*/ + + .ui.inverted.cards > .card, + .ui.inverted.card { + background: @invertedBackground; + box-shadow: @invertedBoxShadow; + } + + /* Content */ + .ui.inverted.cards > .card > .content, + .ui.inverted.card > .content { + border-top: @invertedContentDivider; + } + + /* Header */ + .ui.inverted.cards > .card > .content > .header, + .ui.inverted.card > .content > .header { + color: @invertedHeaderColor; + } + + /* Description */ + .ui.inverted.cards > .card > .content > .description, + .ui.inverted.card > .content > .description { + color: @invertedDescriptionColor; + } + + /* Meta */ + .ui.inverted.cards > .card .meta, + .ui.inverted.card .meta { + color: @invertedMetaColor; + } + .ui.inverted.cards > .card .meta > a:not(.ui), + .ui.inverted.card .meta > a:not(.ui) { + color: @invertedMetaLinkColor; + } + .ui.inverted.cards > .card .meta > a:not(.ui):hover, + .ui.inverted.card .meta > a:not(.ui):hover { + color: @invertedMetaLinkHoverColor; + } + + /* Extra */ + .ui.inverted.cards > .card > .extra, + .ui.inverted.card > .extra { + border-top: @invertedExtraDivider !important; + color: @invertedExtraColor; + } + .ui.inverted.cards > .card > .extra a:not(.ui), + .ui.inverted.card > .extra a:not(.ui) { + color: @invertedExtraLinkColor; + } + .ui.inverted.cards > .card > .extra a:not(.ui):hover, + .ui.inverted.card > .extra a:not(.ui):hover { + color: @extraLinkHoverColor; + } + + /* Link card(s) */ + .ui.inverted.cards a.card:hover, + .ui.inverted.link.cards .card:not(.icon):hover, + a.inverted.ui.card:hover, + .ui.inverted.link.card:hover { + background: @invertedLinkHoverBackground; + } +} + + +.loadUIOverrides(); diff --git a/semantic/src/definitions/views/comment.less b/semantic/src/definitions/views/comment.less new file mode 100644 index 0000000..fedf40e --- /dev/null +++ b/semantic/src/definitions/views/comment.less @@ -0,0 +1,291 @@ +/*! + * # Fomantic-UI - Comment + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + + +/******************************* + Theme +*******************************/ + +@type : 'view'; +@element : 'comment'; + +@import (multiple) '../../theme.config'; + +/******************************* + Standard +*******************************/ + + +/*-------------- + Comments +---------------*/ + +.ui.comments { + margin: @margin; + max-width: @maxWidth; +} + +.ui.comments:first-child { + margin-top: 0; +} +.ui.comments:last-child { + margin-bottom: 0; +} + +/*-------------- + Comment +---------------*/ + +.ui.comments .comment { + position: relative; + background: @commentBackground; + margin: @commentMargin; + padding: @commentPadding; + border: @commentBorder; + border-top: @commentDivider; + line-height: @commentLineHeight; +} +.ui.comments .comment:first-child { + margin-top: @firstCommentMargin; + padding-top: @firstCommentPadding; +} + + +/*-------------------- + Nested Comments +---------------------*/ + +.ui.comments .comment > .comments { + margin: @nestedCommentsMargin; + padding: @nestedCommentsPadding; +} +.ui.comments .comment > .comments:before{ + position: absolute; + top: 0; + left: 0; +} +.ui.comments .comment > .comments .comment { + border: @nestedCommentBorder; + border-top: @nestedCommentDivider; + background: @nestedCommentBackground; +} + +/*-------------- + Avatar +---------------*/ + +.ui.comments .comment .avatar { + display: @avatarDisplay; + width: @avatarWidth; + height: @avatarHeight; + float: @avatarFloat; + margin: @avatarMargin; +} +.ui.comments .comment img.avatar, +.ui.comments .comment .avatar img { + display: block; + margin: 0 auto; + width: 100%; + height: 100%; + border-radius: @avatarBorderRadius; +} + +/*-------------- + Content +---------------*/ + +.ui.comments .comment > .content { + display: block; +} +/* If there is an avatar move content over */ +.ui.comments .comment > .avatar ~ .content { + margin-left: @contentMargin; +} + +/*-------------- + Author +---------------*/ + +.ui.comments .comment .author { + font-size: @authorFontSize; + color: @authorColor; + font-weight: @authorFontWeight; +} +.ui.comments .comment a.author { + cursor: pointer; +} +.ui.comments .comment a.author:hover { + color: @authorHoverColor; +} + +/*-------------- + Metadata +---------------*/ + +.ui.comments .comment .metadata { + display: @metadataDisplay; + margin-left: @metadataSpacing; + color: @metadataColor; + font-size: @metadataFontSize; +} +.ui.comments .comment .metadata > * { + display: inline-block; + margin: 0 @metadataContentSpacing 0 0; +} +.ui.comments .comment .metadata > :last-child { + margin-right: 0; +} + +/*-------------------- + Comment Text +---------------------*/ + +.ui.comments .comment .text { + margin: @textMargin; + font-size: @textFontSize; + word-wrap: @textWordWrap; + color: @textColor; + line-height: @textLineHeight; +} + + +/*-------------------- + User Actions +---------------------*/ + +.ui.comments .comment .actions { + font-size: @actionFontSize; +} +.ui.comments .comment .actions a { + cursor: pointer; + display: inline-block; + margin: 0 @actionContentDistance 0 0; + color: @actionLinkColor; +} +.ui.comments .comment .actions a:last-child { + margin-right: 0; +} +.ui.comments .comment .actions a.active, +.ui.comments .comment .actions a:hover { + color: @actionLinkHoverColor; +} + +/*-------------------- + Reply Form +---------------------*/ + +.ui.comments > .reply.form { + margin-top: @replyDistance; +} +.ui.comments .comment .reply.form { + width: 100%; + margin-top: @commentReplyDistance; +} +.ui.comments .reply.form textarea { + font-size: @replyFontSize; + height: @replyHeight; +} + +/******************************* + State +*******************************/ + +.ui.collapsed.comments, +.ui.comments .collapsed.comments, +.ui.comments .collapsed.comment { + display: none; +} + + +/******************************* + Variations +*******************************/ + +& when (@variationCommentThreaded) { + /*-------------------- + Threaded + ---------------------*/ + + .ui.threaded.comments .comment > .comments { + margin: @threadedCommentMargin; + padding: @threadedCommentPadding; + box-shadow: @threadedCommentBoxShadow; + } +} + +& when (@variationCommentMinimal) { + /*-------------------- + Minimal + ---------------------*/ + + .ui.minimal.comments .comment .actions { + opacity: 0; + position: @minimalActionPosition; + top: @minimalActionTop; + right: @minimalActionRight; + left: @minimalActionLeft; + transition: @minimalTransition; + transition-delay: @minimalTransitionDelay; + } + .ui.minimal.comments .comment > .content:hover > .actions { + opacity: 1; + } +} + + +/*------------------- + Sizes +--------------------*/ + +.ui.comments { + font-size: @medium; +} +& when not (@variationCommentSizes = false) { + each(@variationCommentSizes, { + @s: @@value; + .ui.@{value}.comments { + font-size: @s; + } + }) +} + + +& when (@variationCommentInverted) { + /*------------------- + Inverted + --------------------*/ + .ui.inverted.comments .comment { + background-color: @black; + } + + .ui.inverted.comments .comment .author, + .ui.inverted.comments .comment .text { + color: @invertedTextColor; + } + + .ui.inverted.comments .comment .metadata, + .ui.inverted.comments .comment .actions a { + color: @invertedLightTextColor; + } + + .ui.inverted.comments .comment a.author:hover, + .ui.inverted.comments .comment .actions a.active, + .ui.inverted.comments .comment .actions a:hover { + color: @invertedHoveredTextColor; + } + & when (@variationCommentThreaded) { + .ui.inverted.threaded.comments .comment > .comments { + box-shadow: -1px 0 0 @solidWhiteBorderColor; + } + } +} + + +.loadUIOverrides(); diff --git a/semantic/src/definitions/views/feed.less b/semantic/src/definitions/views/feed.less new file mode 100644 index 0000000..20efe8f --- /dev/null +++ b/semantic/src/definitions/views/feed.less @@ -0,0 +1,304 @@ +/*! + * # Fomantic-UI - Feed + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +/******************************* + Theme +*******************************/ + +@type : 'view'; +@element : 'feed'; + +@import (multiple) '../../theme.config'; + +/******************************* + Activity Feed +*******************************/ + +.ui.feed { + margin: @margin; +} +.ui.feed:first-child { + margin-top: 0; +} +.ui.feed:last-child { + margin-bottom: 0; +} + + +/******************************* + Content +*******************************/ + +/* Event */ +.ui.feed > .event { + display: flex; + flex-direction: row; + width: @eventWidth; + padding: @eventPadding; + margin: @eventMargin; + background: @eventBackground; + border-top: @eventDivider; +} +.ui.feed > .event:first-child { + border-top: 0; + padding-top: 0; +} +.ui.feed > .event:last-child { + padding-bottom: 0; +} + +/* Event Label */ +.ui.feed > .event > .label { + display: block; + flex: 0 0 auto; + width: @labelWidth; + height: @labelHeight; + align-self: @labelAlignSelf; + text-align: @labelTextAlign; +} +.ui.feed > .event > .label .icon { + opacity: @iconLabelOpacity; + font-size: @iconLabelSize; + width: @iconLabelWidth; + padding: @iconLabelPadding; + background: @iconLabelBackground; + border: @iconLabelBorder; + border-radius: @iconLabelBorderRadius; + color: @iconLabelColor; +} +.ui.feed > .event > .label img { + width: @imageLabelWidth; + height: @imageLabelHeight; + border-radius: @imageLabelBorderRadius; +} +.ui.feed > .event > .label + .content { + margin: @labeledContentMargin; +} + +/*-------------- + Content +---------------*/ + +/* Content */ +.ui.feed > .event > .content { + display: block; + flex: 1 1 auto; + align-self: @contentAlignSelf; + text-align: @contentTextAlign; + word-wrap: @contentWordWrap; +} +.ui.feed > .event:last-child > .content { + padding-bottom: @lastLabeledContentPadding; +} + +/* Link */ +.ui.feed > .event > .content a { + cursor: pointer; +} + +/*-------------- + Date +---------------*/ + +.ui.feed > .event > .content .date { + margin: @dateMargin; + padding: @datePadding; + color: @dateColor; + font-weight: @dateFontWeight; + font-size: @dateFontSize; + font-style: @dateFontStyle; +} + +/*-------------- + Summary +---------------*/ + +.ui.feed > .event > .content .summary { + margin: @summaryMargin; + font-size: @summaryFontSize; + font-weight: @summaryFontWeight; + color: @summaryColor; +} + +/* Summary Image */ +.ui.feed > .event > .content .summary img { + display: inline-block; + width: @summaryImageWidth; + height: @summaryImageHeight; + margin: @summaryImageMargin; + border-radius: @summaryImageBorderRadius; + vertical-align: @summaryImageVerticalAlign; +} +/*-------------- + User +---------------*/ + +.ui.feed > .event > .content .user { + display: inline-block; + font-weight: @userFontWeight; + margin-right: @userDistance; + vertical-align: baseline; +} +.ui.feed > .event > .content .user img { + margin: @userImageMargin; + width: @userImageWidth; + height: @userImageHeight; + vertical-align: @userImageVerticalAlign; +} +/*-------------- + Inline Date +---------------*/ + +/* Date inside Summary */ +.ui.feed > .event > .content .summary > .date { + display: @summaryDateDisplay; + float: @summaryDateFloat; + font-weight: @summaryDateFontWeight; + font-size: @summaryDateFontSize; + font-style: @summaryDateFontStyle; + margin: @summaryDateMargin; + padding: @summaryDatePadding; + color: @summaryDateColor; +} + +/*-------------- + Extra Summary +---------------*/ + +.ui.feed > .event > .content .extra { + margin: @extraMargin; + background: @extraBackground; + padding: @extraPadding; + color: @extraColor; +} + +/* Images */ +.ui.feed > .event > .content .extra.images img { + display: inline-block; + margin: @extraImageMargin; + width: @extraImageWidth; +} + +/* Text */ +.ui.feed > .event > .content .extra.text { + padding: @extraTextPadding; + border-left: @extraTextPointer; + font-size: @extraTextFontSize; + max-width: @extraTextMaxWidth; + line-height: @extraTextLineHeight; +} + +/*-------------- + Meta +---------------*/ + +.ui.feed > .event > .content .meta { + display: @metadataDisplay; + font-size: @metadataFontSize; + margin: @metadataMargin; + background: @metadataBackground; + border: @metadataBorder; + border-radius: @metadataBorderRadius; + box-shadow: @metadataBoxShadow; + padding: @metadataPadding; + color: @metadataColor; +} + +.ui.feed > .event > .content .meta > * { + position: relative; + margin-left: @metadataElementSpacing; +} +.ui.feed > .event > .content .meta > *:after { + content: @metadataDivider; + color: @metadataDividerColor; + top: 0; + left: @metadataDividerOffset; + opacity: 1; + position: absolute; + vertical-align: top; +} + +.ui.feed > .event > .content .meta .like { + color: @likeColor; + transition: @likeTransition; +} +.ui.feed > .event > .content .meta .like:hover i.icon { + color: @likeHoverColor; +} +.ui.feed > .event > .content .meta .active.like i.icon { + color: @likeActiveColor; +} + +/* First element */ +.ui.feed > .event > .content .meta > :first-child { + margin-left: 0; +} +.ui.feed > .event > .content .meta > :first-child::after { + display: none; +} + +/* Action */ +.ui.feed > .event > .content .meta a, +.ui.feed > .event > .content .meta > i.icon { + cursor: @metadataActionCursor; + opacity: @metadataActionOpacity; + color: @metadataActionColor; + transition: @metadataActionTransition; +} +.ui.feed > .event > .content .meta a:hover, +.ui.feed > .event > .content .meta a:hover i.icon, +.ui.feed > .event > .content .meta > i.icon:hover { + color: @metadataActionHoverColor; +} + + + +/******************************* + Variations +*******************************/ + +.ui.feed { + font-size: @medium; +} +& when not (@variationFeedSizes = false) { + each(@variationFeedSizes, { + @s: @@value; + .ui.@{value}.feed { + font-size: @s; + } + }) +} + +& when (@variationFeedInverted) { + /*------------------ + Inverted + -------------------*/ + + .ui.inverted.feed > .event { + background: @black; + } + + .ui.inverted.feed > .event > .content .date, + .ui.inverted.feed > .event > .content .meta .like { + color: @invertedLightTextColor; + } + + .ui.inverted.feed > .event > .content .summary, + .ui.inverted.feed > .event > .content .extra.text { + color: @invertedTextColor; + } + + .ui.inverted.feed > .event > .content .meta .like:hover { + color: @invertedSelectedTextColor; + } +} + + +.loadUIOverrides(); diff --git a/semantic/src/definitions/views/item.less b/semantic/src/definitions/views/item.less new file mode 100644 index 0000000..2c9ed2e --- /dev/null +++ b/semantic/src/definitions/views/item.less @@ -0,0 +1,559 @@ +/*! + * # Fomantic-UI - Item + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +/******************************* + Theme +*******************************/ + +@type : 'view'; +@element : 'item'; + +@import (multiple) '../../theme.config'; + +/******************************* + Standard +*******************************/ + +/*-------------- + Item +---------------*/ + +.ui.items > .item { + display: @display; + margin: @itemSpacing 0; + width: @width; + min-height: @minHeight; + background: @background; + padding: @padding; + + border: @border; + border-radius: @borderRadius; + box-shadow: @boxShadow; + transition: @transition; + z-index: @zIndex; +} +.ui.items > .item a { + cursor: pointer; +} + +/*-------------- + Items +---------------*/ + +.ui.items { + margin: @groupMargin; +} + +.ui.items:first-child { + margin-top: 0 !important; +} +.ui.items:last-child { + margin-bottom: 0 !important; +} + +/*-------------- + Item +---------------*/ + +.ui.items > .item:after { + display: block; + content: ' '; + height: 0; + clear: both; + overflow: hidden; + visibility: hidden; +} +.ui.items > .item:first-child { + margin-top: 0; +} +.ui.items > .item:last-child { + margin-bottom: 0; +} + + + +/*-------------- + Images +---------------*/ + +.ui.items > .item > .image { + position: relative; + flex: 0 0 auto; + display: @imageDisplay; + float: @imageFloat; + margin: @imageMargin; + padding: @imagePadding; + max-height: @imageMaxHeight; + align-self: @imageVerticalAlign; +} +.ui.items > .item > .image > img { + display: block; + width: 100%; + height: auto; + border-radius: @imageBorderRadius; + border: @imageBorder; +} + +.ui.items > .item > .image:only-child > img { + border-radius: @borderRadius; +} + + +/*-------------- + Content +---------------*/ + +.ui.items > .item > .content { + display: block; + flex: 1 1 auto; + background: @contentBackground; + color: @contentColor; + margin: @contentMargin; + padding: @contentPadding; + box-shadow: @contentBoxShadow; + font-size: @contentFontSize; + border: @contentBorder; + border-radius: @contentBorderRadius; +} +.ui.items > .item > .content:after { + display: block; + content: ' '; + height: 0; + clear: both; + overflow: hidden; + visibility: hidden; +} + +.ui.items > .item > .image + .content { + min-width: 0; + width: @contentWidth; + display: @contentDisplay; + margin-left: @contentOffset; + align-self: @contentVerticalAlign; + padding-left: @contentImageDistance; +} + +.ui.items > .item > .content > .header { + display: inline-block; + margin: @headerMargin; + font-family: @headerFont; + font-weight: @headerFontWeight; + color: @headerColor; +} +/* Default Header Size */ +.ui.items > .item > .content > .header:not(.ui) { + font-size: @headerFontSize; +} + +/*-------------- + Floated +---------------*/ + +.ui.items > .item [class*="left floated"] { + float: left; +} +.ui.items > .item [class*="right floated"] { + float: right; +} + + +/*-------------- + Content Image +---------------*/ + +.ui.items > .item .content img { + align-self: @contentImageVerticalAlign; + width: @contentImageWidth; +} +.ui.items > .item img.avatar, +.ui.items > .item .avatar img { + width: @avatarSize; + height: @avatarSize; + border-radius: @avatarBorderRadius; +} + + +/*-------------- + Description +---------------*/ + +.ui.items > .item > .content > .description { + margin-top: @descriptionDistance; + max-width: @descriptionMaxWidth; + font-size: @descriptionFontSize; + line-height: @descriptionLineHeight; + color: @descriptionColor; +} + +/*-------------- + Paragraph +---------------*/ + +.ui.items > .item > .content p { + margin: 0 0 @paragraphDistance; +} +.ui.items > .item > .content p:last-child { + margin-bottom: 0; +} + +/*-------------- + Meta +---------------*/ + +.ui.items > .item .meta { + margin: @metaMargin; + font-size: @metaFontSize; + line-height: @metaLineHeight; + color: @metaColor; +} +.ui.items > .item .meta * { + margin-right: @metaSpacing; +} +.ui.items > .item .meta :last-child { + margin-right: 0; +} + +.ui.items > .item .meta [class*="right floated"] { + margin-right: 0; + margin-left: @metaSpacing; +} + +/*-------------- + Links +---------------*/ + +/* Generic */ +.ui.items > .item > .content a:not(.ui) { + color: @contentLinkColor; + transition: @contentLinkTransition; +} +.ui.items > .item > .content a:not(.ui):hover { + color: @contentLinkHoverColor; +} + +/* Header */ +.ui.items > .item > .content > a.header { + color: @headerLinkColor; +} +.ui.items > .item > .content > a.header:hover { + color: @headerLinkHoverColor; +} + +/* Meta */ +.ui.items > .item .meta > a:not(.ui) { + color: @metaLinkColor; +} +.ui.items > .item .meta > a:not(.ui):hover { + color: @metaLinkHoverColor; +} + + + +/*-------------- + Labels +---------------*/ + +/*-----Star----- */ + +/* Icon */ +.ui.items > .item > .content .favorite.icon { + cursor: pointer; + opacity: @actionOpacity; + transition: @actionTransition; +} +.ui.items > .item > .content .favorite.icon:hover { + opacity: @actionHoverOpacity; + color: @favoriteColor; +} +.ui.items > .item > .content .active.favorite.icon { + color: @favoriteActiveColor; +} + +/*-----Like----- */ + +/* Icon */ +.ui.items > .item > .content .like.icon { + cursor: pointer; + opacity: @actionOpacity; + transition: @actionTransition; +} +.ui.items > .item > .content .like.icon:hover { + opacity: @actionHoverOpacity; + color: @likeColor; +} +.ui.items > .item > .content .active.like.icon { + color: @likeActiveColor; +} + +/*---------------- + Extra Content +-----------------*/ + +.ui.items > .item .extra { + display: @extraDisplay; + position: @extraPosition; + background: @extraBackground; + margin: @extraMargin; + width: @extraWidth; + padding: @extraPadding; + top: @extraTop; + left: @extraLeft; + color: @extraColor; + box-shadow: @extraBoxShadow; + transition: @extraTransition; + border-top: @extraDivider; +} +.ui.items > .item .extra > * { + margin: (@extraRowSpacing / 2) @extraHorizontalSpacing (@extraRowSpacing / 2) 0; +} +.ui.items > .item .extra > [class*="right floated"] { + margin: (@extraRowSpacing / 2) 0 (@extraRowSpacing / 2) @extraHorizontalSpacing; +} + +.ui.items > .item .extra:after { + display: block; + content: ' '; + height: 0; + clear: both; + overflow: hidden; + visibility: hidden; +} + + +/******************************* + Responsive +*******************************/ + +/* Default Image Width */ +.ui.items > .item > .image:not(.ui) { + width: @imageWidth; +} + + +/* Tablet Only */ +@media only screen and (min-width: @tabletBreakpoint) and (max-width: @largestTabletScreen) { + .ui.items > .item { + margin: @tabletItemSpacing 0; + } + .ui.items > .item > .image:not(.ui) { + width: @tabletImageWidth; + } + .ui.items > .item > .image + .content { + display: block; + padding: 0 0 0 @tabletContentImageDistance; + } + +} + +/* Mobile Only */ +@media only screen and (max-width: @largestMobileScreen) { + .ui.items:not(.unstackable) > .item { + flex-direction: column; + margin: @mobileItemSpacing 0; + } + .ui.items:not(.unstackable) > .item > .image { + display: block; + margin-left: auto; + margin-right: auto; + } + .ui.items:not(.unstackable) > .item > .image, + .ui.items:not(.unstackable) > .item > .image > img { + max-width: 100% !important; + width: @mobileImageWidth !important; + max-height: @mobileImageMaxHeight !important; + } + .ui.items:not(.unstackable) > .item > .image + .content { + display: block; + padding: @mobileContentImageDistance 0 0; + } +} + + +/******************************* + Variations +*******************************/ + +& when (@variationItemAligned) { + /*------------------- + Aligned + --------------------*/ + + .ui.items > .item > .image + [class*="top aligned"].content { + align-self: flex-start; + } + .ui.items > .item > .image + [class*="middle aligned"].content { + align-self: center; + } + .ui.items > .item > .image + [class*="bottom aligned"].content { + align-self: flex-end; + } +} + +& when (@variationItemRelaxed) { + /*-------------- + Relaxed + ---------------*/ + + .ui.relaxed.items > .item { + margin: @relaxedItemSpacing 0; + } + .ui[class*="very relaxed"].items > .item { + margin: @veryRelaxedItemSpacing 0; + } +} + +& when (@variationItemDivided) { + /*------------------- + Divided + --------------------*/ + + .ui.divided.items > .item { + border-top: @dividedBorder; + margin: @dividedMargin; + padding: @dividedPadding; + } + .ui.divided.items > .item:first-child { + border-top: none; + margin-top: @dividedFirstLastMargin !important; + padding-top: @dividedFirstLastPadding !important; + } + .ui.divided.items > .item:last-child { + margin-bottom: @dividedFirstLastMargin !important; + padding-bottom: @dividedFirstLastPadding !important; + } + & when (@variationItemRelaxed) { + /* Relaxed Divided */ + .ui.relaxed.divided.items > .item { + margin: 0; + padding: @relaxedItemSpacing 0; + } + .ui[class*="very relaxed"].divided.items > .item { + margin: 0; + padding: @veryRelaxedItemSpacing 0; + } + } +} + +& when (@variationItemLink) { + /*------------------- + Link + --------------------*/ + + .ui.items a.item:hover, + .ui.link.items > .item:hover { + cursor: pointer; + } + + .ui.items a.item:hover .content .header, + .ui.link.items > .item:hover .content .header { + color: @headerLinkHoverColor; + } +} + + +/*-------------- + Size +---------------*/ + +.ui.items > .item { + font-size: @relativeMedium; +} +& when not (@variationItemSizes = false) { + each(@variationItemSizes, { + @s: @{value}ItemSize; + .ui.@{value}.items > .item { + font-size: @@s; + } + }) +} + +& when (@variationItemUnstackable) { + /*--------------- + Unstackable + ----------------*/ + + @media only screen and (max-width: @largestMobileScreen) { + .ui.unstackable.items > .item > .image, + .ui.unstackable.items > .item > .image > img { + width: @unstackableMobileImageWidth !important; + } + } +} + +& when (@variationItemInverted) { + /*-------------- + Inverted + ---------------*/ + + .ui.inverted.items > .item { + background: @invertedBackground; + } + .ui.inverted.items > .item > .content { + background: @invertedContentBackground; + color: @invertedContentColor; + } + .ui.inverted.items > .item .extra { + background: @invertedExtraBackground; + } + .ui.inverted.items > .item > .content > .header { + color: @invertedHeaderColor; + } + .ui.inverted.items > .item > .content > .description { + color: @invertedDescriptionColor; + } + .ui.inverted.items > .item .meta { + color: @invertedMetaColor; + } + .ui.inverted.items > .item > .content a:not(.ui) { + color: @invertedContentLinkColor; + } + .ui.inverted.items > .item > .content a:not(.ui):hover { + color: @invertedContentLinkHoverColor; + } + .ui.inverted.items > .item > .content > a.header { + color: @invertedHeaderLinkColor; + } + .ui.inverted.items > .item > .content > a.header:hover { + color: @invertedHeaderLinkHoverColor; + } + .ui.inverted.items > .item .meta > a:not(.ui) { + color: @invertedMetaLinkColor; + } + .ui.inverted.items > .item .meta > a:not(.ui):hover { + color: @invertedMetaLinkHoverColor; + } + .ui.inverted.items > .item > .content .favorite.icon:hover { + color: @invertedFavoriteColor; + } + .ui.inverted.items > .item > .content .active.favorite.icon { + color: @invertedFavoriteActiveColor; + } + .ui.inverted.items > .item > .content .like.icon:hover { + color: @invertedLikeColor; + } + .ui.inverted.items > .item > .content .active.like.icon { + color: @invertedLikeActiveColor; + } + .ui.inverted.items > .item .extra { + color: @invertedExtraColor; + } + .ui.inverted.items a.item:hover .content .header, + .ui.inverted.link.items > .item:hover .content .header { + color: @invertedHeaderLinkHoverColor; + } + .ui.inverted.divided.items > .item { + border-top: @invertedDividedBorder; + } + .ui.inverted.divided.items > .item:first-child { + border-top: none; + } +} + +.loadUIOverrides(); diff --git a/semantic/src/definitions/views/statistic.less b/semantic/src/definitions/views/statistic.less new file mode 100644 index 0000000..9145aeb --- /dev/null +++ b/semantic/src/definitions/views/statistic.less @@ -0,0 +1,421 @@ +/*! + * # Fomantic-UI - Statistic + * http://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +/******************************* + Theme +*******************************/ + +@type : 'view'; +@element : 'statistic'; + +@import (multiple) '../../theme.config'; + +/******************************* + Statistic +*******************************/ + +/* Standalone */ +.ui.statistic { + display: inline-flex; + flex-direction: column; + margin: @margin; + max-width: @maxWidth; +} + +.ui.statistic + .ui.statistic { + margin: 0 0 0 @horizontalSpacing; +} + +.ui.statistic:first-child { + margin-top: 0; +} +.ui.statistic:last-child { + margin-bottom: 0; +} + + + +/******************************* + Group +*******************************/ + +/* Grouped */ +.ui.statistics { + display: flex; + align-items: flex-start; + flex-wrap: wrap; +} +.ui.statistics > .statistic { + display: inline-flex; + flex: 0 1 auto; + flex-direction: column; + margin: @elementMargin; + max-width: @elementMaxWidth; +} +.ui.statistics { + display: flex; + margin: @groupMargin; +} + +/* Clearing */ +.ui.statistics:after { + display: block; + content: ' '; + height: 0; + clear: both; + overflow: hidden; + visibility: hidden; +} + +.ui.statistics:first-child { + margin-top: 0; +} + + +/******************************* + Content +*******************************/ + + +/*-------------- + Value +---------------*/ + +.ui.statistics .statistic > .value, +.ui.statistic > .value { + font-family: @valueFont; + font-size: @valueSize; + font-weight: @valueFontWeight; + line-height: @valueLineHeight; + color: @valueColor; + text-transform: @valueTextTransform; + text-align: @textAlign; +} + +/*-------------- + Label +---------------*/ + +.ui.statistics .statistic > .label, +.ui.statistic > .label { + font-family: @labelFont; + font-size: @labelSize; + font-weight: @labelFontWeight; + color: @labelColor; + text-transform: @labelTextTransform; + text-align: @textAlign; +} + +/* Top Label */ +.ui.statistics .statistic > .label ~ .value, +.ui.statistic > .label ~ .value { + margin-top: @topLabelDistance; +} + +/* Bottom Label */ +.ui.statistics .statistic > .value ~ .label, +.ui.statistic > .value ~ .label { + margin-top: @bottomLabelDistance; +} + + + +/******************************* + Types +*******************************/ + +/*-------------- + Icon Value +---------------*/ + +.ui.statistics .statistic > .value > i.icon, +.ui.statistic > .value > i.icon { + opacity: 1; + width: auto; + margin: 0; +} + +/*-------------- + Text Value +---------------*/ + +.ui.statistics .statistic > .text.value, +.ui.statistic > .text.value { + line-height: @textValueLineHeight; + min-height: @textValueMinHeight; + font-weight: @textValueFontWeight; + text-align: center; +} +.ui.statistics .statistic > .text.value + .label, +.ui.statistic > .text.value + .label { + text-align: center; +} + +/*-------------- + Image Value +---------------*/ + +.ui.statistics .statistic > .value img, +.ui.statistic > .value img { + max-height: @imageHeight; + vertical-align: @imageVerticalAlign; +} + + + +/******************************* + Variations +*******************************/ + + +/*-------------- + Count +---------------*/ + + +.ui.ten.statistics { + margin: @itemGroupMargin; +} +.ui.ten.statistics .statistic { + min-width: @tenColumn; + margin: @itemMargin; +} + +.ui.nine.statistics { + margin: @itemGroupMargin; +} +.ui.nine.statistics .statistic { + min-width: @nineColumn; + margin: @itemMargin; +} + +.ui.eight.statistics { + margin: @itemGroupMargin; +} +.ui.eight.statistics .statistic { + min-width: @eightColumn; + margin: @itemMargin; +} + +.ui.seven.statistics { + margin: @itemGroupMargin; +} +.ui.seven.statistics .statistic { + min-width: @sevenColumn; + margin: @itemMargin; +} + +.ui.six.statistics { + margin: @itemGroupMargin; +} +.ui.six.statistics .statistic { + min-width: @sixColumn; + margin: @itemMargin; +} + +.ui.five.statistics { + margin: @itemGroupMargin; +} +.ui.five.statistics .statistic { + min-width: @fiveColumn; + margin: @itemMargin; +} + +.ui.four.statistics { + margin: @itemGroupMargin; +} +.ui.four.statistics .statistic { + min-width: @fourColumn; + margin: @itemMargin; +} + +.ui.three.statistics { + margin: @itemGroupMargin; +} +.ui.three.statistics .statistic { + min-width: @threeColumn; + margin: @itemMargin; +} + +.ui.two.statistics { + margin: @itemGroupMargin; +} +.ui.two.statistics .statistic { + min-width: @twoColumn; + margin: @itemMargin; +} + +.ui.one.statistics { + margin: @itemGroupMargin; +} +.ui.one.statistics .statistic { + min-width: @oneColumn; + margin: @itemMargin; +} + + + +& when (@variationStatisticHorizontal) { + /*-------------- + Horizontal + ---------------*/ + + .ui.horizontal.statistic { + flex-direction: row; + align-items: center; + } + .ui.horizontal.statistics { + flex-direction: column; + margin: 0; + max-width: none; + } + .ui.horizontal.statistics .statistic { + flex-direction: row; + align-items: center; + max-width: none; + margin: @horizontalGroupElementMargin; + } + + .ui.horizontal.statistic > .text.value, + .ui.horizontal.statistics > .statistic > .text.value { + min-height: 0 !important; + } + .ui.horizontal.statistics .statistic > .value > i.icon, + .ui.horizontal.statistic > .value > i.icon { + width: @iconWidth; + } + + .ui.horizontal.statistics .statistic > .value, + .ui.horizontal.statistic > .value { + display: inline-block; + vertical-align: middle; + } + .ui.horizontal.statistics .statistic > .label, + .ui.horizontal.statistic > .label { + display: inline-block; + vertical-align: middle; + margin: 0 0 0 @horizontalLabelDistance; + } +} + +& when (@variationStatisticInverted) { + /*-------------- + Inverted + ---------------*/ + + .ui.inverted.statistics .statistic > .value, + .ui.inverted.statistic .value { + color: @invertedValueColor; + } + .ui.inverted.statistics .statistic > .label, + .ui.inverted.statistic .label { + color: @invertedLabelColor; + } +} + +/*-------------- + Colors +---------------*/ + +each(@colors,{ + @color: replace(@key,'@',''); + @c: @colors[@@color][color]; + @l: @colors[@@color][light]; + + .ui.@{color}.statistics .statistic > .value, + .ui.statistics .@{color}.statistic > .value, + .ui.@{color}.statistic > .value { + color: @c; + } + & when (@variationStatisticInverted) { + .ui.inverted.@{color}.statistics .statistic > .value, + .ui.statistics .inverted.@{color}.statistic > .value, + .ui.inverted.@{color}.statistic > .value { + color: @l; + } + } +}) + +& when (@variationStatisticFloated) { + /*-------------- + Floated + ---------------*/ + + .ui[class*="left floated"].statistic { + float: left; + margin: @leftFloatedMargin; + } + .ui[class*="right floated"].statistic { + float: right; + margin: @rightFloatedMargin; + } + .ui.floated.statistic:last-child { + margin-bottom: 0; + } +} + +& when (@variationStatisticStackable) { + /*-------------- + Stackable + ---------------*/ + + @media only screen and (max-width: @largestMobileScreen) { + .ui.stackable.statistics { + width: auto; + margin-left: 0 !important; + margin-right: 0 !important; + } + .ui.stackable.statistics > .statistic { + width: 100% !important; + margin: 0 0 !important; + padding: (@stackableRowSpacing / 2) (@stackableGutter / 2) !important; + } + } +} + +/*-------------- + Sizes +---------------*/ + + +/* Medium */ +.ui.statistics .statistic > .value, +.ui.statistic > .value { + font-size: @valueSize; +} +.ui.horizontal.statistics .statistic > .value, +.ui.horizontal.statistic > .value { + font-size: @horizontalValueSize; +} +.ui.statistics .statistic > .text.value, +.ui.statistic > .text.value { + font-size: @textValueSize; +} +& when not (@variationStatisticSizes = false) { + each(@variationStatisticSizes, { + @s: @{value}ValueSize; + @hs: @{value}HorizontalValueSize; + @ts: @{value}TextValueSize; + .ui.@{value}.statistics .statistic > .value, + .ui.@{value}.statistic > .value { + font-size: @@s; + } + .ui.@{value}.horizontal.statistics .statistic > .value, + .ui.@{value}.horizontal.statistic > .value { + font-size: @@hs; + } + .ui.@{value}.statistics .statistic > .text.value, + .ui.@{value}.statistic > .text.value { + font-size: @@ts; + } + }) +} + +.loadUIOverrides(); |