mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-04-25 14:59:30 +00:00
MODULE-TYPO
- Sass set-up - md-list - md-theming (install)
This commit is contained in:
44
UI/WebServerResources/scss/vendors/angular-material/components/textField/textField-theme.scss
vendored
Normal file
44
UI/WebServerResources/scss/vendors/angular-material/components/textField/textField-theme.scss
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
md-input-group.md-THEME_NAME-theme {
|
||||
input, textarea {
|
||||
text-shadow: '{{foreground-shadow}}';
|
||||
@include input-placeholder-color('{{foreground-3}}');
|
||||
}
|
||||
|
||||
label {
|
||||
text-shadow: '{{foreground-shadow}}';
|
||||
color: '{{foreground-3}}';
|
||||
}
|
||||
|
||||
input, textarea {
|
||||
color: '{{foreground-1}}';
|
||||
border-color: '{{foreground-4}}';
|
||||
}
|
||||
|
||||
&.md-input-focused {
|
||||
input, textarea {
|
||||
border-color: '{{primary-500}}';
|
||||
}
|
||||
label {
|
||||
color: '{{primary-500}}';
|
||||
}
|
||||
&.md-accent {
|
||||
input, textarea {
|
||||
border-color: '{{accent-500}}';
|
||||
}
|
||||
label {
|
||||
color: '{{accent-500}}';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.md-input-has-value:not(.md-input-focused) {
|
||||
label {
|
||||
color: '{{foreground-2}}';
|
||||
}
|
||||
}
|
||||
|
||||
.md-input[disabled] {
|
||||
border-bottom-color: '{{foreground-4}}';
|
||||
color: '{{foreground-3}}';
|
||||
}
|
||||
}
|
||||
134
UI/WebServerResources/scss/vendors/angular-material/components/textField/textField.js
vendored
Normal file
134
UI/WebServerResources/scss/vendors/angular-material/components/textField/textField.js
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc module
|
||||
* @name material.components.textField
|
||||
* @description
|
||||
* Form
|
||||
*/
|
||||
angular.module('material.components.textField', [
|
||||
'material.core'
|
||||
])
|
||||
.directive('mdInputGroup', mdInputGroupDirective)
|
||||
.directive('mdInput', mdInputDirective)
|
||||
.directive('mdTextFloat', mdTextFloatDirective);
|
||||
|
||||
|
||||
function mdTextFloatDirective($mdTheming, $mdUtil, $parse, $log) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
scope : {
|
||||
fid : '@?mdFid',
|
||||
label : '@?',
|
||||
value : '=ngModel'
|
||||
},
|
||||
compile : function(element, attr) {
|
||||
|
||||
$log.warn('<md-text-float> is deprecated. Please use `<md-input-container>` and `<input>`.' +
|
||||
'More information at http://material.angularjs.org/#/api/material.components.input/directive/mdInputContainer');
|
||||
|
||||
if ( angular.isUndefined(attr.mdFid) ) {
|
||||
attr.mdFid = $mdUtil.nextUid();
|
||||
}
|
||||
|
||||
return {
|
||||
pre : function(scope, element, attrs) {
|
||||
var disabledParsed = $parse(attrs.ngDisabled);
|
||||
scope.isDisabled = function() {
|
||||
return disabledParsed(scope.$parent);
|
||||
};
|
||||
|
||||
scope.inputType = attrs.type || "text";
|
||||
},
|
||||
post: $mdTheming
|
||||
};
|
||||
},
|
||||
template:
|
||||
'<md-input-group tabindex="-1">' +
|
||||
' <label for="{{fid}}" >{{label}}</label>' +
|
||||
' <md-input id="{{fid}}" ng-disabled="isDisabled()" ng-model="value" type="{{inputType}}"></md-input>' +
|
||||
'</md-input-group>'
|
||||
};
|
||||
}
|
||||
|
||||
function mdInputGroupDirective($log) {
|
||||
return {
|
||||
restrict: 'CE',
|
||||
controller: ['$element', function($element) {
|
||||
|
||||
$log.warn('<md-input-group> is deprecated. Please use `<md-input-container>` and `<input>`.' +
|
||||
'More information at http://material.angularjs.org/#/api/material.components.input/directive/mdInputContainer');
|
||||
this.setFocused = function(isFocused) {
|
||||
$element.toggleClass('md-input-focused', !!isFocused);
|
||||
};
|
||||
this.setHasValue = function(hasValue) {
|
||||
$element.toggleClass('md-input-has-value', hasValue );
|
||||
};
|
||||
}]
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
function mdInputDirective($mdUtil, $log) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
template: '<input >',
|
||||
require: ['^?mdInputGroup', '?ngModel'],
|
||||
link: function(scope, element, attr, ctrls) {
|
||||
if ( !ctrls[0] ) return;
|
||||
|
||||
$log.warn('<md-input> is deprecated. Please use `<md-input-container>` and `<input>`.' +
|
||||
'More information at http://material.angularjs.org/#/api/material.components.input/directive/mdInputContainer');
|
||||
|
||||
var inputGroupCtrl = ctrls[0];
|
||||
var ngModelCtrl = ctrls[1];
|
||||
|
||||
scope.$watch(scope.isDisabled, function(isDisabled) {
|
||||
element.attr('aria-disabled', !!isDisabled);
|
||||
element.attr('tabindex', !!isDisabled);
|
||||
});
|
||||
element.attr('type', attr.type || element.parent().attr('type') || "text");
|
||||
|
||||
// When the input value changes, check if it "has" a value, and
|
||||
// set the appropriate class on the input group
|
||||
if (ngModelCtrl) {
|
||||
//Add a $formatter so we don't use up the render function
|
||||
ngModelCtrl.$formatters.push(function(value) {
|
||||
inputGroupCtrl.setHasValue( isNotEmpty(value) );
|
||||
return value;
|
||||
});
|
||||
}
|
||||
|
||||
element
|
||||
.on('input', function() {
|
||||
inputGroupCtrl.setHasValue( isNotEmpty() );
|
||||
})
|
||||
.on('focus', function(e) {
|
||||
// When the input focuses, add the focused class to the group
|
||||
inputGroupCtrl.setFocused(true);
|
||||
})
|
||||
.on('blur', function(e) {
|
||||
// When the input blurs, remove the focused class from the group
|
||||
inputGroupCtrl.setFocused(false);
|
||||
inputGroupCtrl.setHasValue( isNotEmpty() );
|
||||
});
|
||||
|
||||
scope.$on('$destroy', function() {
|
||||
inputGroupCtrl.setFocused(false);
|
||||
inputGroupCtrl.setHasValue(false);
|
||||
});
|
||||
|
||||
|
||||
function isNotEmpty(value) {
|
||||
value = angular.isUndefined(value) ? element.val() : value;
|
||||
return (angular.isDefined(value) && (value!==null) &&
|
||||
(value.toString().trim() !== ""));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
})();
|
||||
148
UI/WebServerResources/scss/vendors/angular-material/components/textField/textField.scss
vendored
Normal file
148
UI/WebServerResources/scss/vendors/angular-material/components/textField/textField.scss
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
$tff-font-size: 0.75em !default;
|
||||
$tff-line-height:26px !default;
|
||||
$tff-transition: all 0.15s $swift-ease-in-out-timing-function !default;
|
||||
// - `label` element (aka hint)
|
||||
$tff-hint-offset-large : 22px !default;
|
||||
$tff-hint-offset-small : 4px !default;
|
||||
$ttf-hint-offset-scale : 0.75 !default;
|
||||
// - `line` element
|
||||
$tff-line-focused-width: 2px !default;
|
||||
$tff-line-disabled-width: 0px !default;
|
||||
$tff-line-dot-width: 1px !default;
|
||||
$tff-line-dot-size: 3px !default;
|
||||
$tff-line-dashed: #cfcfcf !default;
|
||||
|
||||
$tff-margin: 10px 0 (10px - $tff-line-focused-width) 0 !default;
|
||||
|
||||
// ******************************
|
||||
// Mixins: Text Fields
|
||||
// ******************************
|
||||
|
||||
@mixin text-field($transition:false, $borderWidth:1px ) {
|
||||
input, textarea {
|
||||
border-bottom-width: $borderWidth;
|
||||
|
||||
@if( $transition != false ) {
|
||||
transition: $transition;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin text-hint($size:large, $transition:false ) {
|
||||
label {
|
||||
@if $size == "small" {
|
||||
transform: translate3d(0, $tff-hint-offset-small, 0) scale($ttf-hint-offset-scale);
|
||||
} @else {
|
||||
transform: translate3d(0, $tff-hint-offset-large, 0);
|
||||
transform-origin: left center;
|
||||
transition: $tff-transition;
|
||||
}
|
||||
|
||||
@if( $transition != false ) {
|
||||
transition: $transition;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin text-dashed-line( $dotGap, $dotSize) {
|
||||
background-size: $dotSize $dotGap;
|
||||
background-position: 0 bottom;
|
||||
background-size: (1px + 1px) $dotGap;
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
|
||||
md-input-group,
|
||||
.md-input-group {
|
||||
|
||||
label {
|
||||
display: block;
|
||||
font-size: $tff-font-size;
|
||||
}
|
||||
|
||||
textarea,
|
||||
input[type="text"],
|
||||
input[type="password"],
|
||||
input[type="datetime"],
|
||||
input[type="datetime-local"],
|
||||
input[type="date"],
|
||||
input[type="month"],
|
||||
input[type="time"],
|
||||
input[type="week"],
|
||||
input[type="number"],
|
||||
input[type="email"],
|
||||
input[type="url"],
|
||||
input[type="search"],
|
||||
input[type="tel"],
|
||||
input[type="color"] {
|
||||
display: block;
|
||||
border-width: 0 0 1px 0;
|
||||
padding-top: 2px;
|
||||
line-height: $tff-line-height;
|
||||
padding-bottom: 1px;
|
||||
|
||||
&:focus {
|
||||
outline: 0;
|
||||
}
|
||||
}
|
||||
|
||||
input, textarea {
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
|
||||
// Light-Theme
|
||||
md-input-group,
|
||||
.md-input-group {
|
||||
padding-bottom: $tff-line-focused-width;
|
||||
margin: $tff-margin;
|
||||
|
||||
position: relative;
|
||||
display: block;
|
||||
|
||||
label {
|
||||
font-size: 1em;
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
|
||||
&:hover {
|
||||
cursor: text;
|
||||
}
|
||||
}
|
||||
|
||||
@include text-hint( large, $tff-transition );
|
||||
@include text-field( $tff-transition );
|
||||
|
||||
|
||||
&.md-input-focused {
|
||||
@include text-hint( small );
|
||||
@include text-field( false, $tff-line-focused-width );
|
||||
input {
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
&.md-input-has-value {
|
||||
@include text-hint( small );
|
||||
|
||||
&:not(.md-input-focused) {
|
||||
@include text-hint( small );
|
||||
}
|
||||
}
|
||||
|
||||
&[disabled] {
|
||||
|
||||
@include text-field( false, $tff-line-disabled-width );
|
||||
input, textarea {
|
||||
@include text-dashed-line( $tff-line-dot-width, $tff-line-dot-size);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@include text-hint( small );
|
||||
|
||||
*:not(.md-input-has-value) {
|
||||
@include text-hint( large );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
295
UI/WebServerResources/scss/vendors/angular-material/components/textField/textField.spec.js
vendored
Normal file
295
UI/WebServerResources/scss/vendors/angular-material/components/textField/textField.spec.js
vendored
Normal file
@@ -0,0 +1,295 @@
|
||||
describe('Text Field directives', function() {
|
||||
beforeEach(module('material.components.textField'));
|
||||
|
||||
describe('- mdInputGroup', function() {
|
||||
var scope;
|
||||
|
||||
beforeEach(function() {
|
||||
scope = {
|
||||
user : {
|
||||
firstName: 'Thomas',
|
||||
lastName: 'Burleson',
|
||||
email: 'ThomasBurleson@gmail.com',
|
||||
password: 'your password is incorrect'
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
it('should set input class for focus & blur', function() {
|
||||
var expressions = {label:"Firstname", model:"user.firstName"},
|
||||
el = setupInputGroup( expressions, scope),
|
||||
input = el.find('input');
|
||||
|
||||
input.triggerHandler('focus');
|
||||
expect(el.hasClass('md-input-focused')).toBe(true);
|
||||
input.triggerHandler('blur');
|
||||
expect(el.hasClass('md-input-focused')).toBe(false);
|
||||
});
|
||||
|
||||
it('should set input class for input event', function() {
|
||||
var expressions = {label:"email", model:"user.email", type:"email"},
|
||||
el = setupInputGroup( expressions, scope),
|
||||
input = el.find('input');
|
||||
|
||||
expect(el.hasClass('md-input-has-value')).toBe(true);
|
||||
|
||||
input.val('');
|
||||
input.triggerHandler('input');
|
||||
expect(el.hasClass('md-input-has-value')).toBe(false);
|
||||
|
||||
input.val('ThomasBurleson@gmail.com');
|
||||
input.triggerHandler('input');
|
||||
expect(el.hasClass('md-input-has-value')).toBe(true);
|
||||
});
|
||||
|
||||
it('should set input class for ngModel render', function() {
|
||||
var expressions = {label:"Firstname", model:"user.firstName"},
|
||||
el = setupInputGroup( expressions, scope),
|
||||
input = el.find('input');
|
||||
|
||||
expect(el.hasClass('md-input-has-value')).toBe(true);
|
||||
|
||||
input.scope().$apply('user.firstName = ""');
|
||||
expect(el.hasClass('md-input-has-value')).toBe(false);
|
||||
|
||||
input.scope().$apply('user.firstName = "Thomas"');
|
||||
expect(el.hasClass('md-input-has-value')).toBe(true);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe(' - mdTextFloat', function() {
|
||||
var model;
|
||||
beforeEach(function() {
|
||||
model = {
|
||||
labels : {
|
||||
firstName: 'FirstName',
|
||||
lastName: 'LastName',
|
||||
email: 'eMail',
|
||||
password: 'Password'
|
||||
},
|
||||
user : {
|
||||
firstName: 'Andrew',
|
||||
lastName: 'Joslin',
|
||||
email: 'AndrewJoslin@drifty.com',
|
||||
password: 'public'
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
it('should set input type `password` properly', function() {
|
||||
var el = setupTextFloat( { type:"password" }, model);
|
||||
expect( el.find('input').attr('type')).toBe("password");
|
||||
expect( el.find('input').val()).toBe("");
|
||||
});
|
||||
it('should set input type `email` properly', function() {
|
||||
var el = setupTextFloat( { type:"email" }, model);
|
||||
expect( el.find('input').attr('type')).toBe("email");
|
||||
expect( el.find('input').val()).toBe("");
|
||||
});
|
||||
|
||||
it('should set a static label properly', function() {
|
||||
var el = setupTextFloat( { label:"motto" }, model);
|
||||
expect( el.find('label').text() ).toBe("motto");
|
||||
|
||||
expect( el.find('input').attr('type')).toBe("text");
|
||||
expect( el.find('input').val()).toBe("");
|
||||
});
|
||||
it('should update a label from model changes.', function() {
|
||||
var markup ='<md-text-float ' +
|
||||
' label="{{labels.firstName}}" ' +
|
||||
' ng-model="user.firstName" >' +
|
||||
'</md-text-float>';
|
||||
var el = buildElement( markup, model);
|
||||
|
||||
expect( el.find('input').val() ).toBe("Andrew");
|
||||
expect( el.find('label').text() ).toBe("FirstName");
|
||||
|
||||
// Change model value of the `firstName` [field] label
|
||||
// then check if the dom is updated
|
||||
|
||||
var val2 = "Corporate Title:";
|
||||
el.find('label').scope().$apply(function(){
|
||||
model.labels.firstName = val2;
|
||||
});
|
||||
expect( el.find('label').text() ).toBe( val2 );
|
||||
|
||||
});
|
||||
it('should update an input value from model changes.', function() {
|
||||
var markup ='<md-text-float ' +
|
||||
' label="{{labels.firstName}}" ' +
|
||||
' ng-model="user.firstName" >' +
|
||||
'</md-text-float>';
|
||||
var el = buildElement( markup, model);
|
||||
var input = el.find('input');
|
||||
|
||||
expect( input.val() ).toBe("Andrew");
|
||||
|
||||
var name = "AngularJS";
|
||||
input.scope().$apply(function(){
|
||||
model.user.firstName = name;
|
||||
});
|
||||
expect( input.val() ).toBe( name );
|
||||
|
||||
});
|
||||
|
||||
// Breaks on IE
|
||||
xit('should update a model value from input changes.', function() {
|
||||
var markup ='<md-text-float ' +
|
||||
' label="{{labels.firstName}}" ' +
|
||||
' ng-model="user.firstName" >' +
|
||||
'</md-text-float>';
|
||||
var el = buildElement( markup, model);
|
||||
var input = el.find('input');
|
||||
|
||||
expect( input.val() ).toBe( model.user.firstName );
|
||||
|
||||
input.val( "AngularJS" );
|
||||
input.triggerHandler('input');
|
||||
expect( model.user.firstName ).toBe( "AngularJS" );
|
||||
|
||||
});
|
||||
|
||||
it('should set input class for focus & blur', function() {
|
||||
var expressions = {label:"Firstname", model:"user.firstName"},
|
||||
el = setupTextFloat( expressions, model),
|
||||
input = el.find('input');
|
||||
|
||||
input.triggerHandler('focus');
|
||||
expect(el.hasClass('md-input-focused')).toBe(true);
|
||||
input.triggerHandler('blur');
|
||||
expect(el.hasClass('md-input-focused')).toBe(false);
|
||||
});
|
||||
it('should set input class for input event', function() {
|
||||
var expressions = {label:"password", model:"user.password", type:"password"},
|
||||
el = setupTextFloat( expressions, model),
|
||||
input = el.find('input');
|
||||
|
||||
expect(el.hasClass('md-input-has-value')).toBe(true);
|
||||
|
||||
input.val('');
|
||||
input.triggerHandler('input');
|
||||
expect(el.hasClass('md-input-has-value')).toBe(false);
|
||||
|
||||
input.val('ThomasBurleson@gmail.com');
|
||||
input.triggerHandler('input');
|
||||
expect(el.hasClass('md-input-has-value')).toBe(true);
|
||||
});
|
||||
it('should set input class for ngModel changes', function() {
|
||||
var expressions = {label:"Password", model:"user.password", type:"password"},
|
||||
el = setupTextFloat( expressions, model),
|
||||
input = el.find('input');
|
||||
|
||||
expect(el.hasClass('md-input-has-value')).toBe(true);
|
||||
|
||||
input.scope().$apply(function(){ model.user.password = ""; });
|
||||
expect(el.hasClass('md-input-has-value')).toBe(false);
|
||||
|
||||
input.scope().$apply(function() { model.user.password = "hiddenValley"; });
|
||||
expect(el.hasClass('md-input-has-value')).toBe(true);
|
||||
});
|
||||
|
||||
it('should pair input and label for accessibility.', function() {
|
||||
var markup ='<md-text-float ' +
|
||||
' md-fid="093" ' +
|
||||
' label="{{labels.firstName}}" ' +
|
||||
' ng-model="user.firstName" >' +
|
||||
'</md-text-float>';
|
||||
var el = buildElement( markup, model);
|
||||
var input = el.find('input');
|
||||
var label = el.find('label');
|
||||
|
||||
expect( label.attr('for') ).toBe( "093" );
|
||||
expect( input.attr('id') ).toBe( label.attr('for') );
|
||||
});
|
||||
|
||||
it('should auto-pair input and label for accessibility.', function() {
|
||||
var markup ='<md-text-float ' +
|
||||
' label="{{labels.firstName}}" ' +
|
||||
' ng-model="user.firstName" >' +
|
||||
'</md-text-float>';
|
||||
var el = buildElement( markup, model);
|
||||
var input = el.find('input');
|
||||
var label = el.find('label');
|
||||
|
||||
expect( label.attr('for') == "" ).toBe( false );
|
||||
expect( input.attr('id') ).toBe( label.attr('for') );
|
||||
});
|
||||
|
||||
it('should add an ARIA attribute for disabled inputs', function() {
|
||||
var markup ='<md-text-float ng-disabled="true" ' +
|
||||
' label="{{labels.firstName}}" ' +
|
||||
' ng-model="user.firstName" >' +
|
||||
'</md-text-float>';
|
||||
var el = buildElement( markup, model);
|
||||
var input = el.find('input');
|
||||
|
||||
expect( input.attr('aria-disabled') ).toBe( 'true' );
|
||||
});
|
||||
});
|
||||
|
||||
// ****************************************************************
|
||||
// Utility `setup` methods
|
||||
// ****************************************************************
|
||||
|
||||
var templates = {
|
||||
md_text_float : '<md-text-float ' +
|
||||
' type="{{type}}" ' +
|
||||
' label="{{label}}" ' +
|
||||
' ng-model="{{model}}" >' +
|
||||
'</md-text-float>',
|
||||
|
||||
md_input_group: '<div class="md-input-group" tabindex="-1">' +
|
||||
' <label>{{label}}</label>' +
|
||||
' <md-input id="{{id}}" type="{{type}}" ng-model="{{model}}"></md-input>' +
|
||||
'</div>'
|
||||
};
|
||||
|
||||
/**
|
||||
* Build a text float group using the `<md-input-group />` markup template
|
||||
*/
|
||||
function setupInputGroup(expressions, values) {
|
||||
values = angular.extend({},{type:"text", id:''},values||{});
|
||||
|
||||
return buildElement( templates.md_input_group, values, angular.extend({}, expressions||{}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a text float group using the `<md-text-float />` markup template
|
||||
*/
|
||||
function setupTextFloat(expressions, values) {
|
||||
values = angular.extend({ modelValue:"",type:'text' }, values || {});
|
||||
|
||||
var defaults = {model:"modelValue", label:""};
|
||||
var tokens = angular.extend({}, defaults, expressions||{} );
|
||||
|
||||
return buildElement( templates.md_text_float, values, tokens );
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the specified template markup, $compile to the DOM build
|
||||
* and link both the bindings and attribute assignments.
|
||||
* @returns {*} DOM Element
|
||||
*/
|
||||
function buildElement( template, scope, interpolationScope ) {
|
||||
var el;
|
||||
|
||||
inject(function($compile, $interpolate, $rootScope) {
|
||||
scope = angular.extend( $rootScope.$new(), scope || {});
|
||||
|
||||
// First substitute interpolation values into the template... if any
|
||||
if ( interpolationScope ) {
|
||||
template = $interpolate( template )( interpolationScope );
|
||||
}
|
||||
|
||||
// Compile the template using the scope model(s)
|
||||
el = $compile( template )( scope );
|
||||
$rootScope.$apply();
|
||||
|
||||
});
|
||||
return el;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user