MODULE-TYPO

- Sass set-up
- md-list
- md-theming (install)
This commit is contained in:
iRouge
2015-01-16 07:52:29 -05:00
parent ec1b4b9b0c
commit f1d2b8cb75
312 changed files with 26839 additions and 1309 deletions

View File

@@ -0,0 +1,58 @@
<div ng-app="inputBasicDemo" ng-controller="DemoCtrl" layout="column">
<md-content md-theme="docs-dark" class="md-padding" layout="row" layout-sm="column">
<md-input-container>
<label>Title</label>
<input ng-model="user.title">
</md-input-container>
<md-input-container>
<label>Email</label>
<input ng-model="user.email" type="email">
</md-input-container>
</md-content>
<md-content class="md-padding">
<md-input-container flex>
<label>Company (Disabled)</label>
<input ng-model="user.company" disabled>
</md-input-container>
<div layout layout-sm="column">
<md-input-container flex>
<label>First Name</label>
<input ng-model="user.firstName">
</md-input-container>
<md-input-container flex>
<label>Last Name</label>
<input ng-model="user.lastName">
</md-input-container>
</div>
<md-input-container flex>
<label>Address</label>
<input ng-model="user.address">
</md-input-container>
<div layout layout-sm="column">
<md-input-container flex>
<label>City</label>
<input ng-model="user.city">
</md-input-container>
<md-input-container flex>
<label>State</label>
<input ng-model="user.state">
</md-input-container>
<md-input-container flex>
<label>Postal Code</label>
<input ng-model="user.postalCode">
</md-input-container>
</div>
<md-input-container flex>
<label>Biography</label>
<textarea ng-model="user.biography" columns="1"></textarea>
</md-input-container>
</md-content>
</div>

View File

@@ -0,0 +1,16 @@
angular.module('inputBasicDemo', ['ngMaterial'])
.controller('DemoCtrl', function($scope) {
$scope.user = {
title: 'Developer',
email: 'ipsum@lorem.com',
firstName: '',
lastName: '' ,
company: 'Google' ,
address: '1600 Amphitheatre Pkwy' ,
city: 'Mountain View' ,
state: 'CA' ,
biography: 'Loves kittens, snowboarding, and can type at 130 WPM. And rumor has it she bouldered up Castle Craig!',
postalCode : '94043'
};
});

View File

@@ -0,0 +1,50 @@
md-input-container.md-THEME_NAME-theme {
.md-input {
@include input-placeholder-color('{{foreground-3}}');
color: '{{foreground-1}}';
border-color: '{{foreground-4}}';
text-shadow: '{{foreground-shadow}}';
}
label {
text-shadow: '{{foreground-shadow}}';
color: '{{foreground-3}}';
}
&.md-input-focused {
.md-input {
border-color: '{{primary-500}}';
}
label {
color: '{{primary-500}}';
}
&.md-accent {
.md-input {
border-color: '{{accent-500}}';
}
label {
color: '{{accent-500}}';
}
}
&.md-warn {
.md-input {
border-color: '{{warn-500}}';
}
label {
color: '{{warn-500}}';
}
}
}
&.md-input-has-value:not(.md-input-focused) {
label {
color: '{{foreground-2}}';
}
}
.md-input[disabled] {
border-bottom-color: transparent;
color: '{{foreground-3}}';
background-image: linear-gradient(to right, '{{foreground-4}}' 0%, '{{foreground-4}}' 33%, transparent 0%);
}
}

View File

@@ -0,0 +1,189 @@
(function() {
/**
* @ngdoc module
* @name material.components.input
*/
angular.module('material.components.input', [
'material.core'
])
.directive('mdInputContainer', mdInputContainerDirective)
.directive('label', labelDirective)
.directive('input', inputTextareaDirective)
.directive('textarea', inputTextareaDirective);
/**
* @ngdoc directive
* @name mdInputContainer
* @module material.components.input
*
* @restrict E
*
* @description
* `<md-input-container>` is the parent of any input or textarea element.
*
* Input and textarea elements will not behave properly unless the md-input-container
* parent is provided.
*
* @usage
* <hljs lang="html">
*
* <md-input-container>
* <label>Username</label>
* <input type="text" ng-model="user.name">
* </md-input-container>
*
* <md-input-container>
* <label>Description</label>
* <textarea ng-model="user.description"></textarea>
* </md-input-container>
*
* </hljs>
*/
function mdInputContainerDirective($mdTheming) {
return {
restrict: 'E',
link: postLink,
controller: ContainerCtrl
};
function postLink(scope, element, attr) {
$mdTheming(element);
}
function ContainerCtrl($scope, $element, $mdUtil) {
var self = this;
self.setFocused = function(isFocused) {
$element.toggleClass('md-input-focused', !!isFocused);
};
self.setHasValue = function(hasValue) {
$element.toggleClass('md-input-has-value', !!hasValue);
};
$scope.$watch(function() {
return self.label && self.input;
}, function(hasLabelAndInput) {
if (hasLabelAndInput && !self.label.attr('for')) {
self.label.attr('for', self.input.attr('id'));
}
});
}
}
function labelDirective() {
return {
restrict: 'E',
require: '^?mdInputContainer',
link: function(scope, element, attr, containerCtrl) {
if (!containerCtrl) return;
containerCtrl.label = element;
scope.$on('$destroy', function() {
containerCtrl.label = null;
});
}
};
}
function inputTextareaDirective($mdUtil, $window) {
return {
restrict: 'E',
require: ['^?mdInputContainer', '?ngModel'],
compile: compile,
};
function compile(element) {
element.addClass('md-input');
return postLink;
}
function postLink(scope, element, attr, ctrls) {
var containerCtrl = ctrls[0];
var ngModelCtrl = ctrls[1];
if ( !containerCtrl ) return;
if (element[0].tagName.toLowerCase() === 'textarea') {
setupTextarea();
}
if (containerCtrl.input) {
throw new Error("<md-input-container> can only have *one* <input> or <textarea> child element!");
}
if (!element.attr('id')) {
element.attr('id', 'input_' + $mdUtil.nextUid());
}
containerCtrl.input = element;
// When the input value changes, check if it "has" a value, and
// set the appropriate class on the input group
if (ngModelCtrl) {
ngModelCtrl.$formatters.push(checkHasValue);
ngModelCtrl.$parsers.push(checkHasValue);
} else {
element.on('input', function() {
containerCtrl.setHasValue( (""+element.val()).length > 0 );
});
containerCtrl.setHasValue( (""+element.val()).length > 0 );
}
function checkHasValue(value) {
containerCtrl.setHasValue(!ngModelCtrl.$isEmpty(value));
return value;
}
element
.on('focus', function(e) {
containerCtrl.setFocused(true);
})
.on('blur', function(e) {
containerCtrl.setFocused(false);
});
scope.$on('$destroy', function() {
containerCtrl.setFocused(false);
containerCtrl.setHasValue(false);
containerCtrl.input = null;
});
function setupTextarea() {
var node = element[0];
if (ngModelCtrl) {
ngModelCtrl.$formatters.push(growTextarea);
ngModelCtrl.$parsers.push(growTextarea);
} else {
element.on('input', growTextarea);
growTextarea();
}
element.on('keyup', growTextarea);
element.on('scroll', onScroll);
angular.element($window).on('resize', growTextarea);
scope.$on('$destroy', function() {
angular.element($window).off('resize', growTextarea);
});
function growTextarea(value) {
node.style.height = "auto";
var line = node.scrollHeight - node.offsetHeight;
node.scrollTop = 0;
var height = node.offsetHeight + (line > 0 ? line : 0);
node.style.height = height + 'px';
return value; // for $formatter/$parser
}
function onScroll(e) {
node.scrollTop = 0;
// for smooth new line adding
var line = node.scrollHeight - node.offsetHeight;
var height = node.offsetHeight + line;
node.style.height = height + 'px';
}
}
}
}
})();

View File

@@ -0,0 +1,93 @@
$input-container-padding: 2px !default;
$input-label-default-offset: 24px !default;
$input-label-default-scale: 1.0 !default;
$input-label-float-offset: 4px !default;
$input-label-float-scale: 0.75 !default;
$input-border-width-default: 1px !default;
$input-border-width-focused: 2px !default;
$input-line-height: 26px !default;
$input-padding-top: 2px !default;
md-input-container {
display: flex;
position: relative;
flex-direction: column;
padding: $input-container-padding;
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"] {
/* remove default appearance from all input/textarea */
-moz-appearance: none;
-webkit-appearance: none;
}
textarea {
resize: none;
overflow: hidden;
}
label {
order: 1;
pointer-events: none;
-webkit-font-smoothing: antialiased;
z-index: 1;
transform: translate3d(0, $input-label-default-offset, 0) scale($input-label-default-scale);
transform-origin: left top;
transition: all $swift-ease-out-timing-function 0.2s;
}
/*
* The .md-input class is added to the input/textarea
*/
.md-input {
flex: 1;
order: 2;
display: block;
background: none;
padding-top: $input-padding-top;
padding-bottom: $input-border-width-focused - $input-border-width-default;
border-width: 0 0 $input-border-width-default 0;
line-height: $input-line-height;
-ms-flex-preferred-size: $input-line-height; //IE fix
&:focus {
outline: none;
}
}
&.md-input-focused,
&.md-input-has-value {
label {
transform: translate3d(0,$input-label-float-offset,0) scale($input-label-float-scale);
}
}
&.md-input-focused {
.md-input {
padding-bottom: 0px; // Increase border width by 1px, decrease padding by 1
border-width: 0 0 $input-border-width-focused 0;
}
}
.md-input[disabled] {
background-position: 0 bottom;
// This background-size is coordinated with a linear-gradient set in input-theme.scss
// to create a dotted line under the input.
background-size: 3px 1px;
background-repeat: repeat-x;
}
}

View File

@@ -0,0 +1,58 @@
describe('md-input-container directive', function() {
beforeEach(module('material.components.input'));
function setup(attrs) {
var container;
inject(function($rootScope, $compile) {
container = $compile('<md-input-container><input ' +(attrs||'')+ '><label></label></md-input-container>')($rootScope);
$rootScope.$apply();
});
return container;
}
it('should set focus class on container', function() {
var el = setup();
expect(el).not.toHaveClass('md-input-focused');
el.find('input').triggerHandler('focus');
expect(el).toHaveClass('md-input-focused');
el.find('input').triggerHandler('blur');
expect(el).not.toHaveClass('md-input-focused');
});
it('should set has-value class on container for non-ng-model input', function() {
var el = setup();
expect(el).not.toHaveClass('md-input-has-value');
el.find('input').val('123').triggerHandler('input');
expect(el).toHaveClass('md-input-has-value');
el.find('input').val('').triggerHandler('input');
expect(el).not.toHaveClass('md-input-has-value');
});
it('should set has-value class on container for ng-model input', inject(function($rootScope) {
$rootScope.value = 'test';
var el = setup('ng-model="$root.value"');
expect(el).toHaveClass('md-input-has-value');
$rootScope.$apply('value = "3"');
expect(el).toHaveClass('md-input-has-value');
$rootScope.$apply('value = null');
expect(el).not.toHaveClass('md-input-has-value');
}));
it('should match label to given input id', inject(function($rootScope) {
var el = setup('id="foo"');
expect(el.find('label').attr('for')).toBe('foo');
expect(el.find('input').attr('id')).toBe('foo');
}));
it('should match label to automatic input id', inject(function($rootScope) {
var el = setup();
expect(el.find('input').attr('id')).toBeTruthy();
expect(el.find('label').attr('for')).toBe(el.find('input').attr('id'));
}));
});