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:
4
UI/WebServerResources/scss/vendors/angular-material/components/backdrop/backdrop-theme.scss
vendored
Normal file
4
UI/WebServerResources/scss/vendors/angular-material/components/backdrop/backdrop-theme.scss
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
md-backdrop.md-opaque.md-THEME_NAME-theme {
|
||||
background-color: '{{foreground-4-0.5}}';
|
||||
position: absolute
|
||||
}
|
||||
31
UI/WebServerResources/scss/vendors/angular-material/components/backdrop/backdrop.js
vendored
Normal file
31
UI/WebServerResources/scss/vendors/angular-material/components/backdrop/backdrop.js
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
/*
|
||||
* @ngdoc module
|
||||
* @name material.components.backdrop
|
||||
* @description Backdrop
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name mdBackdrop
|
||||
* @module material.components.backdrop
|
||||
*
|
||||
* @restrict E
|
||||
*
|
||||
* @description
|
||||
* `<md-backdrop>` is a backdrop element used by other coponents, such as dialog and bottom sheet.
|
||||
* Apply class `opaque` to make the backdrop use the theme backdrop color.
|
||||
*
|
||||
*/
|
||||
|
||||
angular.module('material.components.backdrop', [
|
||||
'material.core'
|
||||
])
|
||||
.directive('mdBackdrop', BackdropDirective);
|
||||
|
||||
function BackdropDirective($mdTheming) {
|
||||
return $mdTheming;
|
||||
}
|
||||
})();
|
||||
36
UI/WebServerResources/scss/vendors/angular-material/components/backdrop/backdrop.scss
vendored
Normal file
36
UI/WebServerResources/scss/vendors/angular-material/components/backdrop/backdrop.scss
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
md-backdrop {
|
||||
z-index: $z-index-backdrop;
|
||||
&.md-dialog-backdrop {
|
||||
z-index: $z-index-dialog - 1;
|
||||
}
|
||||
&.md-bottom-sheet-backdrop {
|
||||
z-index: $z-index-bottom-sheet - 1;
|
||||
}
|
||||
&.md-sidenav-backdrop {
|
||||
z-index: $z-index-sidenav - 1;
|
||||
}
|
||||
|
||||
background-color: rgba(0,0,0,0);
|
||||
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
|
||||
&.ng-enter {
|
||||
animation: $swift-ease-out-timing-function mdBackdropFadeIn 0.5s both;
|
||||
}
|
||||
&.ng-leave {
|
||||
animation: $swift-ease-in-timing-function mdBackdropFadeOut 0.2s both;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes mdBackdropFadeIn {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
@keyframes mdBackdropFadeOut {
|
||||
from { opacity: 1; }
|
||||
to { opacity: 0; }
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
|
||||
md-bottom-sheet.md-THEME_NAME-theme {
|
||||
background-color: '{{background-50}}';
|
||||
border-top-color: '{{background-300}}';
|
||||
|
||||
&.md-list {
|
||||
md-item {
|
||||
color: '{{foreground-1}}';
|
||||
}
|
||||
}
|
||||
|
||||
.md-subheader {
|
||||
background-color: '{{background-50}}';
|
||||
}
|
||||
|
||||
.md-subheader {
|
||||
color: '{{foreground-1}}';
|
||||
}
|
||||
}
|
||||
285
UI/WebServerResources/scss/vendors/angular-material/components/bottomSheet/bottomSheet.js
vendored
Normal file
285
UI/WebServerResources/scss/vendors/angular-material/components/bottomSheet/bottomSheet.js
vendored
Normal file
@@ -0,0 +1,285 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc module
|
||||
* @name material.components.bottomSheet
|
||||
* @description
|
||||
* BottomSheet
|
||||
*/
|
||||
angular.module('material.components.bottomSheet', [
|
||||
'material.core',
|
||||
'material.components.backdrop'
|
||||
])
|
||||
.directive('mdBottomSheet', MdBottomSheetDirective)
|
||||
.provider('$mdBottomSheet', MdBottomSheetProvider);
|
||||
|
||||
function MdBottomSheetDirective() {
|
||||
return {
|
||||
restrict: 'E'
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name $mdBottomSheet
|
||||
* @module material.components.bottomSheet
|
||||
*
|
||||
* @description
|
||||
* `$mdBottomSheet` opens a bottom sheet over the app and provides a simple promise API.
|
||||
*
|
||||
* ### Restrictions
|
||||
*
|
||||
* - The bottom sheet's template must have an outer `<md-bottom-sheet>` element.
|
||||
* - Add the `md-grid` class to the bottom sheet for a grid layout.
|
||||
* - Add the `md-list` class to the bottom sheet for a list layout.
|
||||
*
|
||||
* @usage
|
||||
* <hljs lang="html">
|
||||
* <div ng-controller="MyController">
|
||||
* <md-button ng-click="openBottomSheet()">
|
||||
* Open a Bottom Sheet!
|
||||
* </md-button>
|
||||
* </div>
|
||||
* </hljs>
|
||||
* <hljs lang="js">
|
||||
* var app = angular.module('app', ['ngMaterial']);
|
||||
* app.controller('MyController', function($scope, $mdBottomSheet) {
|
||||
* $scope.openBottomSheet = function() {
|
||||
* $mdBottomSheet.show({
|
||||
* template: '<md-bottom-sheet>Hello!</md-bottom-sheet>'
|
||||
* });
|
||||
* };
|
||||
* });
|
||||
* </hljs>
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name $mdBottomSheet#show
|
||||
*
|
||||
* @description
|
||||
* Show a bottom sheet with the specified options.
|
||||
*
|
||||
* @param {object} options An options object, with the following properties:
|
||||
*
|
||||
* - `templateUrl` - `{string=}`: The url of an html template file that will
|
||||
* be used as the content of the bottom sheet. Restrictions: the template must
|
||||
* have an outer `md-bottom-sheet` element.
|
||||
* - `template` - `{string=}`: Same as templateUrl, except this is an actual
|
||||
* template string.
|
||||
* - `controller` - `{string=}`: The controller to associate with this bottom sheet.
|
||||
* - `locals` - `{string=}`: An object containing key/value pairs. The keys will
|
||||
* be used as names of values to inject into the controller. For example,
|
||||
* `locals: {three: 3}` would inject `three` into the controller with the value
|
||||
* of 3.
|
||||
* - `targetEvent` - `{DOMClickEvent=}`: A click's event object. When passed in as an option,
|
||||
* the location of the click will be used as the starting point for the opening animation
|
||||
* of the the dialog.
|
||||
* - `resolve` - `{object=}`: Similar to locals, except it takes promises as values
|
||||
* and the bottom sheet will not open until the promises resolve.
|
||||
* - `controllerAs` - `{string=}`: An alias to assign the controller to on the scope.
|
||||
* - `parent` - `{element=}`: The element to append the bottom sheet to. Defaults to appending
|
||||
* to the root element of the application.
|
||||
*
|
||||
* @returns {promise} A promise that can be resolved with `$mdBottomSheet.hide()` or
|
||||
* rejected with `$mdBottomSheet.cancel()`.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name $mdBottomSheet#hide
|
||||
*
|
||||
* @description
|
||||
* Hide the existing bottom sheet and resolve the promise returned from
|
||||
* `$mdBottomSheet.show()`.
|
||||
*
|
||||
* @param {*=} response An argument for the resolved promise.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name $mdBottomSheet#cancel
|
||||
*
|
||||
* @description
|
||||
* Hide the existing bottom sheet and reject the promise returned from
|
||||
* `$mdBottomSheet.show()`.
|
||||
*
|
||||
* @param {*=} response An argument for the rejected promise.
|
||||
*
|
||||
*/
|
||||
|
||||
function MdBottomSheetProvider($$interimElementProvider) {
|
||||
|
||||
return $$interimElementProvider('$mdBottomSheet')
|
||||
.setDefaults({
|
||||
options: bottomSheetDefaults
|
||||
});
|
||||
|
||||
/* @ngInject */
|
||||
function bottomSheetDefaults($animate, $mdConstant, $timeout, $$rAF, $compile, $mdTheming, $mdBottomSheet, $rootElement) {
|
||||
var backdrop;
|
||||
|
||||
return {
|
||||
themable: true,
|
||||
targetEvent: null,
|
||||
onShow: onShow,
|
||||
onRemove: onRemove,
|
||||
escapeToClose: true
|
||||
};
|
||||
|
||||
function onShow(scope, element, options) {
|
||||
// Add a backdrop that will close on click
|
||||
backdrop = $compile('<md-backdrop class="md-opaque md-bottom-sheet-backdrop">')(scope);
|
||||
backdrop.on('click touchstart', function() {
|
||||
$timeout($mdBottomSheet.cancel);
|
||||
});
|
||||
|
||||
$mdTheming.inherit(backdrop, options.parent);
|
||||
|
||||
$animate.enter(backdrop, options.parent, null);
|
||||
|
||||
var bottomSheet = new BottomSheet(element);
|
||||
options.bottomSheet = bottomSheet;
|
||||
|
||||
// Give up focus on calling item
|
||||
options.targetEvent && angular.element(options.targetEvent.target).blur();
|
||||
$mdTheming.inherit(bottomSheet.element, options.parent);
|
||||
|
||||
return $animate.enter(bottomSheet.element, options.parent)
|
||||
.then(function() {
|
||||
var focusable = angular.element(
|
||||
element[0].querySelector('button') ||
|
||||
element[0].querySelector('a') ||
|
||||
element[0].querySelector('[ng-click]')
|
||||
);
|
||||
focusable.focus();
|
||||
|
||||
if (options.escapeToClose) {
|
||||
options.rootElementKeyupCallback = function(e) {
|
||||
if (e.keyCode === $mdConstant.KEY_CODE.ESCAPE) {
|
||||
$timeout($mdBottomSheet.cancel);
|
||||
}
|
||||
};
|
||||
$rootElement.on('keyup', options.rootElementKeyupCallback);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function onRemove(scope, element, options) {
|
||||
var bottomSheet = options.bottomSheet;
|
||||
$animate.leave(backdrop);
|
||||
return $animate.leave(bottomSheet.element).then(function() {
|
||||
bottomSheet.cleanup();
|
||||
|
||||
// Restore focus
|
||||
options.targetEvent && angular.element(options.targetEvent.target).focus();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* BottomSheet class to apply bottom-sheet behavior to an element
|
||||
*/
|
||||
function BottomSheet(element) {
|
||||
var MAX_OFFSET = 80; // amount past the bottom of the element that we can drag down, this is same as in _bottomSheet.scss
|
||||
var WIGGLE_AMOUNT = 20; // point where it starts to get "harder" to drag
|
||||
var CLOSING_VELOCITY = 10; // how fast we need to flick down to close the sheet
|
||||
var startY, lastY, velocity, transitionDelay, startTarget;
|
||||
|
||||
// coercion incase $mdCompiler returns multiple elements
|
||||
element = element.eq(0);
|
||||
|
||||
element.on('touchstart', onTouchStart)
|
||||
.on('touchmove', onTouchMove)
|
||||
.on('touchend', onTouchEnd);
|
||||
|
||||
return {
|
||||
element: element,
|
||||
cleanup: function cleanup() {
|
||||
element.off('touchstart', onTouchStart)
|
||||
.off('touchmove', onTouchMove)
|
||||
.off('touchend', onTouchEnd);
|
||||
}
|
||||
};
|
||||
|
||||
function onTouchStart(e) {
|
||||
e.preventDefault();
|
||||
startTarget = e.target;
|
||||
startY = getY(e);
|
||||
|
||||
// Disable transitions on transform so that it feels fast
|
||||
transitionDelay = element.css($mdConstant.CSS.TRANSITION_DURATION);
|
||||
element.css($mdConstant.CSS.TRANSITION_DURATION, '0s');
|
||||
}
|
||||
|
||||
function onTouchEnd(e) {
|
||||
// Re-enable the transitions on transforms
|
||||
element.css($mdConstant.CSS.TRANSITION_DURATION, transitionDelay);
|
||||
|
||||
var currentY = getY(e);
|
||||
// If we didn't scroll much, and we didn't change targets, assume its a click
|
||||
if ( Math.abs(currentY - startY) < 5 && e.target == startTarget) {
|
||||
angular.element(e.target).triggerHandler('click');
|
||||
} else {
|
||||
// If they went fast enough, trigger a close.
|
||||
if (velocity > CLOSING_VELOCITY) {
|
||||
$timeout($mdBottomSheet.cancel);
|
||||
|
||||
// Otherwise, untransform so that we go back to our normal position
|
||||
} else {
|
||||
setTransformY(undefined);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onTouchMove(e) {
|
||||
var currentY = getY(e);
|
||||
var delta = currentY - startY;
|
||||
|
||||
velocity = currentY - lastY;
|
||||
lastY = currentY;
|
||||
|
||||
// Do some conversion on delta to get a friction-like effect
|
||||
delta = adjustedDelta(delta);
|
||||
setTransformY(delta + MAX_OFFSET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to find the Y aspect of various touch events.
|
||||
**/
|
||||
function getY(e) {
|
||||
var touch = e.touches && e.touches.length ? e.touches[0] : e.changedTouches[0];
|
||||
return touch.clientY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform the element along the y-axis
|
||||
**/
|
||||
function setTransformY(amt) {
|
||||
if (amt === null || amt === undefined) {
|
||||
element.css($mdConstant.CSS.TRANSFORM, '');
|
||||
} else {
|
||||
element.css($mdConstant.CSS.TRANSFORM, 'translate3d(0, ' + amt + 'px, 0)');
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a new value for delta that will never exceed MAX_OFFSET_AMOUNT
|
||||
// Will get harder to exceed it as you get closer to it
|
||||
function adjustedDelta(delta) {
|
||||
if ( delta < 0 && delta < -MAX_OFFSET + WIGGLE_AMOUNT) {
|
||||
delta = -delta;
|
||||
var base = MAX_OFFSET - WIGGLE_AMOUNT;
|
||||
delta = Math.max(-MAX_OFFSET, -Math.min(MAX_OFFSET - 5, base + ( WIGGLE_AMOUNT * (delta - base)) / MAX_OFFSET) - delta / 50);
|
||||
}
|
||||
|
||||
return delta;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
})();
|
||||
175
UI/WebServerResources/scss/vendors/angular-material/components/bottomSheet/bottomSheet.scss
vendored
Normal file
175
UI/WebServerResources/scss/vendors/angular-material/components/bottomSheet/bottomSheet.scss
vendored
Normal file
@@ -0,0 +1,175 @@
|
||||
$bottom-sheet-horizontal-padding: 2 * $baseline-grid !default;
|
||||
$bottom-sheet-vertical-padding: 1 * $baseline-grid !default;
|
||||
$bottom-sheet-icon-after-margin: 4 * $baseline-grid !default;
|
||||
$bottom-sheet-list-item-height: 6 * $baseline-grid !default;
|
||||
$bottom-sheet-hidden-bottom-padding: 80px !default;
|
||||
$bottom-sheet-header-height: 7 * $baseline-grid !default;
|
||||
$bottom-sheet-grid-font-weight: 300 !default;
|
||||
|
||||
md-bottom-sheet {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
padding: $bottom-sheet-vertical-padding $bottom-sheet-horizontal-padding $bottom-sheet-vertical-padding + $bottom-sheet-hidden-bottom-padding $bottom-sheet-horizontal-padding;
|
||||
z-index: $z-index-bottom-sheet;
|
||||
|
||||
border-top: 1px solid;
|
||||
|
||||
transform: translate3d(0, $bottom-sheet-hidden-bottom-padding, 0);
|
||||
transition: $swift-ease-out;
|
||||
transition-property: transform;
|
||||
|
||||
&.md-has-header {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
&.ng-enter {
|
||||
opacity: 0;
|
||||
transform: translate3d(0, 100%, 0);
|
||||
}
|
||||
|
||||
&.ng-enter-active {
|
||||
opacity: 1;
|
||||
display: block;
|
||||
transform: translate3d(0, $bottom-sheet-hidden-bottom-padding, 0) !important;
|
||||
}
|
||||
|
||||
|
||||
&.ng-leave-active {
|
||||
transform: translate3d(0, 100%, 0) !important;
|
||||
transition: $swift-ease-in;
|
||||
}
|
||||
|
||||
.md-subheader {
|
||||
background-color: transparent;
|
||||
font-family: $font-family;
|
||||
line-height: $bottom-sheet-header-height;
|
||||
padding: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
md-inline-icon {
|
||||
display: inline-block;
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
fill: #444;
|
||||
}
|
||||
|
||||
md-item {
|
||||
display: flex;
|
||||
outline: none;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
&.md-list {
|
||||
md-item {
|
||||
align-items: center;
|
||||
height: $bottom-sheet-list-item-height;
|
||||
|
||||
div.md-icon-container {
|
||||
display: inline-block;
|
||||
height: 3 * $baseline-grid;
|
||||
margin-right: $bottom-sheet-icon-after-margin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
&.md-grid {
|
||||
padding-left: 3 * $baseline-grid;
|
||||
padding-right: 3 * $baseline-grid;
|
||||
padding-top: 0;
|
||||
|
||||
md-list {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
transition: all 0.5s;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
md-item {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
transition: all 0.5s;
|
||||
|
||||
height: 12 * $baseline-grid;
|
||||
|
||||
margin-top: $baseline-grid;
|
||||
margin-bottom: $baseline-grid;
|
||||
|
||||
/* Mixin for how many grid items to show per row */
|
||||
@mixin grid-items-per-row($num, $alignEdges: false) {
|
||||
$width: 100% / $num;
|
||||
flex: 1 1 $width;
|
||||
max-width: $width;
|
||||
|
||||
@if $alignEdges {
|
||||
&:nth-of-type(#{$num}n + 1) {
|
||||
align-items: flex-start;
|
||||
}
|
||||
&:nth-of-type(#{$num}n) {
|
||||
align-items: flex-end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: $layout-breakpoint-sm) {
|
||||
@include grid-items-per-row(3, true);
|
||||
}
|
||||
|
||||
@media screen and (min-width: $layout-breakpoint-sm) and (max-width: $layout-breakpoint-md) {
|
||||
@include grid-items-per-row(4);
|
||||
}
|
||||
|
||||
@media screen and (min-width: $layout-breakpoint-md) and (max-width: $layout-breakpoint-lg) {
|
||||
@include grid-items-per-row(6);
|
||||
}
|
||||
|
||||
@media screen and (min-width: $layout-breakpoint-lg) {
|
||||
@include grid-items-per-row(7);
|
||||
}
|
||||
|
||||
|
||||
|
||||
.md-item-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 6 * $baseline-grid;
|
||||
padding-bottom: 2 * $baseline-grid;
|
||||
}
|
||||
|
||||
.md-grid-item-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 10 * $baseline-grid;
|
||||
}
|
||||
|
||||
.md-icon-container {
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
height: 6 * $baseline-grid;
|
||||
width: 6 * $baseline-grid;
|
||||
margin: 0 0;
|
||||
}
|
||||
|
||||
p.md-grid-text {
|
||||
font-weight: $bottom-sheet-grid-font-weight;
|
||||
line-height: 2 * $baseline-grid;
|
||||
font-size: 2 * $baseline-grid - 3;
|
||||
margin: 0;
|
||||
white-space: nowrap;
|
||||
width: 8 * $baseline-grid;
|
||||
text-align: center;
|
||||
padding-top: 1 * $baseline-grid;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
44
UI/WebServerResources/scss/vendors/angular-material/components/bottomSheet/bottomSheet.spec.js
vendored
Normal file
44
UI/WebServerResources/scss/vendors/angular-material/components/bottomSheet/bottomSheet.spec.js
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
describe('$mdBottomSheet service', function() {
|
||||
beforeEach(module('material.components.bottomSheet', 'ngAnimateMock'));
|
||||
|
||||
describe('#build()', function() {
|
||||
it('should escapeToClose == true', inject(function($mdBottomSheet, $rootScope, $rootElement, $timeout, $animate, $mdConstant) {
|
||||
var parent = angular.element('<div>');
|
||||
$mdBottomSheet.show({
|
||||
template: '<md-bottom-sheet>',
|
||||
parent: parent,
|
||||
escapeToClose: true
|
||||
});
|
||||
$rootScope.$apply();
|
||||
|
||||
$animate.triggerCallbacks();
|
||||
|
||||
expect(parent.find('md-bottom-sheet').length).toBe(1);
|
||||
|
||||
$rootElement.triggerHandler({type: 'keyup',
|
||||
keyCode: $mdConstant.KEY_CODE.ESCAPE
|
||||
});
|
||||
|
||||
$timeout.flush();
|
||||
expect(parent.find('md-bottom-sheet').length).toBe(0);
|
||||
}));
|
||||
|
||||
it('should escapeToClose == false', inject(function($mdBottomSheet, $rootScope, $rootElement, $timeout, $animate, $mdConstant) {
|
||||
var parent = angular.element('<div>');
|
||||
$mdBottomSheet.show({
|
||||
template: '<md-bottom-sheet>',
|
||||
parent: parent,
|
||||
escapeToClose: false
|
||||
});
|
||||
$rootScope.$apply();
|
||||
|
||||
$animate.triggerCallbacks();
|
||||
|
||||
expect(parent.find('md-bottom-sheet').length).toBe(1);
|
||||
|
||||
$rootElement.triggerHandler({ type: 'keyup', keyCode: $mdConstant.KEY_CODE.ESCAPE });
|
||||
|
||||
expect(parent.find('md-bottom-sheet').length).toBe(1);
|
||||
}));
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,14 @@
|
||||
<md-bottom-sheet class="md-grid">
|
||||
<md-list>
|
||||
<md-item ng-repeat="item in items">
|
||||
|
||||
<md-button class="md-grid-item-content" aria-label="{{item.name}}" ng-click="listItemClick($index)">
|
||||
<div class="md-icon-container">
|
||||
<md-inline-grid-icon icon="{{item.icon}}"></md-inline-grid-icon>
|
||||
</div>
|
||||
<p class="md-grid-text"> {{ item.name }} </p>
|
||||
</md-button>
|
||||
|
||||
</md-item>
|
||||
</md-list>
|
||||
</md-bottom-sheet>
|
||||
@@ -0,0 +1,12 @@
|
||||
<md-bottom-sheet class="md-list md-has-header">
|
||||
<md-subheader>Comment Actions</md-subheader>
|
||||
<md-list>
|
||||
<md-item ng-repeat="item in items">
|
||||
<md-button aria-label="{{item.name}}" ng-click="listItemClick($index)">
|
||||
<!-- Using custom inline icon until md-icon is ready. DONT USE ME! -->
|
||||
<md-inline-list-icon icon="{{item.icon}}"></md-inline-list-icon>
|
||||
<span class="md-inline-list-icon-label">{{ item.name }}</span>
|
||||
</md-button>
|
||||
</md-item>
|
||||
</md-list>
|
||||
</md-bottom-sheet>
|
||||
@@ -0,0 +1,19 @@
|
||||
<div ng-controller="BottomSheetExample">
|
||||
<p style="padding-left: 20px;">
|
||||
Bottom sheet can be dismissed with the service or a swipe down.
|
||||
</p>
|
||||
<div class="bottom-sheet-demo inset" layout="column" layout-sm="row" layout-align="center">
|
||||
<md-button class="md-primary" ng-click="showListBottomSheet($event)">
|
||||
Show as List
|
||||
</md-button>
|
||||
<div style="width:50px;"></div>
|
||||
<md-button class="md-primary" ng-click="showGridBottomSheet($event)">
|
||||
Show as Grid
|
||||
</md-button>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
<b layout="row" layout-align="center center" layout-margin>
|
||||
{{alert}}
|
||||
</b>
|
||||
</div>
|
||||
@@ -0,0 +1,58 @@
|
||||
angular.module('bottomSheetDemo1', ['ngMaterial'])
|
||||
|
||||
.controller('BottomSheetExample', function($scope, $timeout, $mdBottomSheet) {
|
||||
$scope.alert = '';
|
||||
|
||||
$scope.showListBottomSheet = function($event) {
|
||||
$scope.alert = '';
|
||||
$mdBottomSheet.show({
|
||||
templateUrl: 'bottom-sheet-list-template.html',
|
||||
controller: 'ListBottomSheetCtrl',
|
||||
targetEvent: $event
|
||||
}).then(function(clickedItem) {
|
||||
$scope.alert = clickedItem.name + ' clicked!';
|
||||
});
|
||||
};
|
||||
|
||||
$scope.showGridBottomSheet = function($event) {
|
||||
$scope.alert = '';
|
||||
$mdBottomSheet.show({
|
||||
templateUrl: 'bottom-sheet-grid-template.html',
|
||||
controller: 'GridBottomSheetCtrl',
|
||||
targetEvent: $event
|
||||
}).then(function(clickedItem) {
|
||||
$scope.alert = clickedItem.name + ' clicked!';
|
||||
});
|
||||
};
|
||||
})
|
||||
|
||||
.controller('ListBottomSheetCtrl', function($scope, $mdBottomSheet) {
|
||||
|
||||
$scope.items = [
|
||||
{ name: 'Share', icon: 'share' },
|
||||
{ name: 'Upload', icon: 'upload' },
|
||||
{ name: 'Copy', icon: 'copy' },
|
||||
{ name: 'Print this page', icon: 'print' },
|
||||
];
|
||||
|
||||
$scope.listItemClick = function($index) {
|
||||
var clickedItem = $scope.items[$index];
|
||||
$mdBottomSheet.hide(clickedItem);
|
||||
};
|
||||
})
|
||||
.controller('GridBottomSheetCtrl', function($scope, $mdBottomSheet) {
|
||||
|
||||
$scope.items = [
|
||||
{ name: 'Hangout', icon: 'hangout' },
|
||||
{ name: 'Mail', icon: 'mail' },
|
||||
{ name: 'Message', icon: 'message' },
|
||||
{ name: 'Copy', icon: 'copy' },
|
||||
{ name: 'Facebook', icon: 'facebook' },
|
||||
{ name: 'Twitter', icon: 'twitter' },
|
||||
];
|
||||
|
||||
$scope.listItemClick = function($index) {
|
||||
var clickedItem = $scope.items[$index];
|
||||
$mdBottomSheet.hide(clickedItem);
|
||||
};
|
||||
});
|
||||
@@ -0,0 +1,64 @@
|
||||
|
||||
/* Temporary fix until md-icon is working, DO NOT USE! */
|
||||
md-inline-list-icon {
|
||||
display: inline-block;
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
}
|
||||
|
||||
.md-inline-list-icon-label {
|
||||
padding-left: 20px;
|
||||
display: inline-block;
|
||||
margin-top: -5px;
|
||||
height: 24px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
md-inline-list-icon[icon=share] {
|
||||
background-image: url('data:image/svg+xml;charset=utf-8;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMjRweCINCgkgaGVpZ2h0PSIyNHB4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDI0IDI0IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxnIGlkPSJIZWFkZXIiPg0KCTxnPg0KCQk8cmVjdCB4PSItNjE4IiB5PSItMTA4MCIgZmlsbD0ibm9uZSIgd2lkdGg9IjE0MDAiIGhlaWdodD0iMzYwMCIvPg0KCTwvZz4NCjwvZz4NCjxnIGlkPSJMYWJlbCI+DQo8L2c+DQo8ZyBpZD0iSWNvbiI+DQoJPGc+DQoJCTxwYXRoIGZpbGw9IiM3ZDdkN2QiIGQ9Ik0yMSwxMWwtNy03djRDNyw5LDQsMTQsMywxOWMyLjUtMy41LDYtNS4xLDExLTUuMVYxOEwyMSwxMXoiLz4NCgkJPHJlY3QgZmlsbD0ibm9uZSIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0Ii8+DQoJPC9nPg0KPC9nPg0KPGcgaWQ9IkdyaWQiIGRpc3BsYXk9Im5vbmUiPg0KCTxnIGRpc3BsYXk9ImlubGluZSI+DQoJPC9nPg0KPC9nPg0KPC9zdmc+');
|
||||
}
|
||||
|
||||
md-inline-list-icon[icon=upload] {
|
||||
background-image: url('data:image/svg+xml;charset=utf-8;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMjRweCINCgkgaGVpZ2h0PSIyNHB4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDI0IDI0IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxnIGlkPSJIZWFkZXIiPg0KCTxnPg0KCQk8cmVjdCB4PSItNjE4IiB5PSItMjIzMiIgZmlsbD0ibm9uZSIgd2lkdGg9IjE0MDAiIGhlaWdodD0iMzYwMCIvPg0KCTwvZz4NCjwvZz4NCjxnIGlkPSJMYWJlbCI+DQo8L2c+DQo8ZyBpZD0iSWNvbiI+DQoJPGc+DQoJCTxyZWN0IGZpbGw9Im5vbmUiIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIvPg0KCQk8cGF0aCBmaWxsPSIjN2Q3ZDdkIiBkPSJNMTkuNCwxMGMtMC43LTMuNC0zLjctNi03LjQtNkM5LjEsNCw2LjYsNS42LDUuNCw4QzIuMyw4LjQsMCwxMC45LDAsMTRjMCwzLjMsMi43LDYsNiw2aDEzYzIuOCwwLDUtMi4yLDUtNQ0KCQkJQzI0LDEyLjQsMjEuOSwxMC4yLDE5LjQsMTB6IE0xNCwxM3Y0aC00di00SDdsNS01bDUsNUgxNHoiLz4NCgk8L2c+DQo8L2c+DQo8ZyBpZD0iR3JpZCIgZGlzcGxheT0ibm9uZSI+DQoJPGcgZGlzcGxheT0iaW5saW5lIj4NCgk8L2c+DQo8L2c+DQo8L3N2Zz4=');
|
||||
}
|
||||
|
||||
md-inline-list-icon[icon=copy] {
|
||||
background-image: url('data:image/svg+xml;charset=utf-8;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMjRweCINCgkgaGVpZ2h0PSIyNHB4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDI0IDI0IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxnIGlkPSJIZWFkZXIiPg0KCTxnPg0KCQk8cmVjdCB4PSItNjE4IiB5PSItMTcyMCIgZmlsbD0ibm9uZSIgd2lkdGg9IjE0MDAiIGhlaWdodD0iMzYwMCIvPg0KCTwvZz4NCjwvZz4NCjxnIGlkPSJMYWJlbHMiPg0KPC9nPg0KPGcgaWQ9Ikljb24iPg0KCTxnPg0KCQk8cmVjdCBmaWxsPSJub25lIiB3aWR0aD0iMjQiIGhlaWdodD0iMjQiLz4NCgkJPHBhdGggZmlsbD0iIzdkN2Q3ZCIgZD0iTTE2LDFINEMyLjksMSwyLDEuOSwyLDN2MTRoMlYzaDEyVjF6IE0xOSw1SDhDNi45LDUsNiw1LjksNiw3djE0YzAsMS4xLDAuOSwyLDIsMmgxMWMxLjEsMCwyLTAuOSwyLTJWNw0KCQkJQzIxLDUuOSwyMC4xLDUsMTksNXogTTE5LDIxSDhWN2gxMVYyMXoiLz4NCgk8L2c+DQo8L2c+DQo8ZyBpZD0iR3JpZCIgZGlzcGxheT0ibm9uZSI+DQoJPGcgZGlzcGxheT0iaW5saW5lIj4NCgk8L2c+DQo8L2c+DQo8L3N2Zz4=');
|
||||
}
|
||||
|
||||
md-inline-list-icon[icon=print] {
|
||||
background-image: url('data:image/svg+xml;charset=utf-8;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMjRweCINCgkgaGVpZ2h0PSIyNHB4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDI0IDI0IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxnIGlkPSJIZWFkZXIiPg0KCTxnPg0KCQk8cmVjdCB4PSItNjE4IiB5PSItMTQ2NCIgZmlsbD0ibm9uZSIgd2lkdGg9IjE0MDAiIGhlaWdodD0iMzYwMCIvPg0KCTwvZz4NCjwvZz4NCjxnIGlkPSJMYWJlbCI+DQo8L2c+DQo8ZyBpZD0iSWNvbiI+DQoJPGc+DQoJCTxnPg0KCQkJPHBhdGggZD0iTTE5LDhINWMtMS43LDAtMywxLjMtMywzdjZoNHY0aDEydi00aDR2LTZDMjIsOS4zLDIwLjcsOCwxOSw4eiBNMTYsMTlIOHYtNWg4VjE5eiBNMTksMTJjLTAuNiwwLTEtMC40LTEtMXMwLjQtMSwxLTENCgkJCQljMC42LDAsMSwwLjQsMSwxUzE5LjYsMTIsMTksMTJ6IE0xOCwzSDZ2NGgxMlYzeiIgZmlsbD0iIzdkN2Q3ZCIvPg0KCQk8L2c+DQoJCTxyZWN0IGZpbGw9Im5vbmUiIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIvPg0KCTwvZz4NCjwvZz4NCjxnIGlkPSJHcmlkIiBkaXNwbGF5PSJub25lIj4NCgk8ZyBkaXNwbGF5PSJpbmxpbmUiPg0KCTwvZz4NCjwvZz4NCjwvc3ZnPg==');
|
||||
}
|
||||
|
||||
.md-icon-container md-inline-grid-icon {
|
||||
display: inline-block;
|
||||
height: 48px;
|
||||
width: 48px;
|
||||
}
|
||||
|
||||
md-inline-grid-icon[icon=hangout] {
|
||||
background-image: url('data:image/svg+xml;charset=utf-8;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iNDhweCINCgkgaGVpZ2h0PSI0OHB4IiB2aWV3Qm94PSIwIDAgNDggNDgiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDQ4IDQ4IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxnIGlkPSJIZWFkZXIiPg0KCTxnPg0KCQk8cmVjdCB4PSItODM4IiB5PSItMjIzMiIgZmlsbD0ibm9uZSIgd2lkdGg9IjE0MDAiIGhlaWdodD0iMzYwMCIvPg0KCTwvZz4NCjwvZz4NCjxnIGlkPSJMYWJlbHMiPg0KPC9nPg0KPGcgaWQ9Ikljb24iPg0KCTxnPg0KCQk8cGF0aCBmaWxsPSIjMTU5RjVDIiBkPSJNMjMsNEMxMy42LDQsNiwxMS42LDYsMjFzNy42LDE3LDE3LDE3aDF2N2M5LjctNC43LDE2LTE1LDE2LTI0QzQwLDExLjYsMzIuNCw0LDIzLDR6IE0yMiwyMmwtMiw0aC0zbDItNGgtM3YtNmg2VjIyeg0KCQkJIE0zMCwyMmwtMiw0aC0zbDItNGgtM3YtNmg2VjIyeiIvPg0KCQk8cmVjdCB4PSIwIiBmaWxsPSJub25lIiB3aWR0aD0iNDgiIGhlaWdodD0iNDgiLz4NCgk8L2c+DQo8L2c+DQo8ZyBpZD0iR3JpZCIgZGlzcGxheT0ibm9uZSI+DQoJPGcgZGlzcGxheT0iaW5saW5lIj4NCgkJPGxpbmUgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDBFNUZGIiBzdHJva2Utd2lkdGg9IjAuMSIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiB4MT0iNDIiIHkxPSItMjIzMiIgeDI9IjQyIiB5Mj0iMTMyMCIvPg0KCTwvZz4NCjwvZz4NCjwvc3ZnPg0K');
|
||||
}
|
||||
|
||||
md-inline-grid-icon[icon=mail] {
|
||||
background-image: url('data:image/svg+xml;charset=utf-8;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iNDhweCINCgkgaGVpZ2h0PSI0OHB4IiB2aWV3Qm94PSIwIDAgNDggNDgiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDQ4IDQ4IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxnIGlkPSJIZWFkZXIiPg0KCTxnPg0KCQk8cmVjdCB4PSItODM4IiB5PSItMjg3MiIgZmlsbD0ibm9uZSIgd2lkdGg9IjE0MDAiIGhlaWdodD0iMzYwMCIvPg0KCTwvZz4NCjwvZz4NCjxnIGlkPSJMYWJlbHMiPg0KPC9nPg0KPGcgaWQ9Ikljb24iPg0KCTxnPg0KCQk8cGF0aCBmaWxsPSIjN2Q3ZDdkIiBkPSJNNDAsOEg4Yy0yLjIsMC00LDEuOC00LDRsMCwyNGMwLDIuMiwxLjgsNCw0LDRoMzJjMi4yLDAsNC0xLjgsNC00VjEyQzQ0LDkuOCw0Mi4yLDgsNDAsOHogTTQwLDE2TDI0LDI2TDgsMTZ2LTRsMTYsMTANCgkJCWwxNi0xMFYxNnoiLz4NCgkJPHJlY3QgZmlsbD0ibm9uZSIgd2lkdGg9IjQ4IiBoZWlnaHQ9IjQ4Ii8+DQoJPC9nPg0KPC9nPg0KPGcgaWQ9IkdyaWQiIGRpc3BsYXk9Im5vbmUiPg0KCTxnIGRpc3BsYXk9ImlubGluZSI+DQoJCTxsaW5lIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwRTVGRiIgc3Ryb2tlLXdpZHRoPSIwLjEiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgeDE9IjQyIiB5MT0iLTI4NzIiIHgyPSI0MiIgeTI9IjY4MCIvPg0KCTwvZz4NCjwvZz4NCjwvc3ZnPg0K');
|
||||
}
|
||||
|
||||
md-inline-grid-icon[icon=message] {
|
||||
background-image: url('data:image/svg+xml;charset=utf-8;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iNDhweCINCgkgaGVpZ2h0PSI0OHB4IiB2aWV3Qm94PSIwIDAgNDggNDgiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDQ4IDQ4IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxnIGlkPSJIZWFkZXIiPg0KCTxnPg0KCQk8cmVjdCB4PSItODM4IiB5PSItMjc0NCIgZmlsbD0ibm9uZSIgd2lkdGg9IjE0MDAiIGhlaWdodD0iMzYwMCIvPg0KCTwvZz4NCjwvZz4NCjxnIGlkPSJMYWJlbHMiPg0KPC9nPg0KPGcgaWQ9Ikljb24iPg0KCTxnPg0KCQk8cGF0aCBmaWxsPSIjN2Q3ZDdkIiBkPSJNNDAsNEg4QzUuOCw0LDQsNS44LDQsOGwwLDM2bDgtOGgyOGMyLjIsMCw0LTEuOCw0LTRWOEM0NCw1LjgsNDIuMiw0LDQwLDR6IE0zNiwyOEgxMnYtNGgyNFYyOHogTTM2LDIySDEydi00aDI0VjIyeg0KCQkJIE0zNiwxNkgxMnYtNGgyNFYxNnoiLz4NCgkJPHJlY3QgeD0iMCIgZmlsbD0ibm9uZSIgd2lkdGg9IjQ4IiBoZWlnaHQ9IjQ4Ii8+DQoJPC9nPg0KPC9nPg0KPGcgaWQ9IkdyaWQiIGRpc3BsYXk9Im5vbmUiPg0KCTxnIGRpc3BsYXk9ImlubGluZSI+DQoJCTxsaW5lIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwRTVGRiIgc3Ryb2tlLXdpZHRoPSIwLjEiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgeDE9IjQyIiB5MT0iLTI3NDQiIHgyPSI0MiIgeTI9IjgwOCIvPg0KCTwvZz4NCjwvZz4NCjwvc3ZnPg0K');
|
||||
}
|
||||
|
||||
md-inline-grid-icon[icon=copy] {
|
||||
background-image: url('data:image/svg+xml;charset=utf-8;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iNDhweCINCgkgaGVpZ2h0PSI0OHB4IiB2aWV3Qm94PSIwIDAgNDggNDgiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDQ4IDQ4IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxnIGlkPSJIZWFkZXIiPg0KCTxnPg0KCQk8cmVjdCB4PSItODM4IiB5PSItMTcyMCIgZmlsbD0ibm9uZSIgd2lkdGg9IjE0MDAiIGhlaWdodD0iMzYwMCIvPg0KCTwvZz4NCjwvZz4NCjxnIGlkPSJMYWJlbHMiPg0KPC9nPg0KPGcgaWQ9Ikljb24iPg0KCTxnPg0KCQk8cmVjdCBmaWxsPSJub25lIiB3aWR0aD0iNDgiIGhlaWdodD0iNDgiLz4NCgkJPHBhdGggZmlsbD0iIzdkN2Q3ZCIgZD0iTTMyLDJIOEM1LjgsMiw0LDMuOCw0LDZ2MjhoNFY2aDI0VjJ6IE0zOCwxMEgxNmMtMi4yLDAtNCwxLjgtNCw0djI4YzAsMi4yLDEuOCw0LDQsNGgyMmMyLjIsMCw0LTEuOCw0LTRWMTQNCgkJCUM0MiwxMS44LDQwLjIsMTAsMzgsMTB6IE0zOCw0MkgxNlYxNGgyMlY0MnoiLz4NCgk8L2c+DQo8L2c+DQo8ZyBpZD0iR3JpZCIgZGlzcGxheT0ibm9uZSI+DQoJPGcgZGlzcGxheT0iaW5saW5lIj4NCgkJPGxpbmUgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDBFNUZGIiBzdHJva2Utd2lkdGg9IjAuMSIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiB4MT0iNDIiIHkxPSItMTcyMCIgeDI9IjQyIiB5Mj0iMTgzMiIvPg0KCTwvZz4NCjwvZz4NCjwvc3ZnPg0K');
|
||||
}
|
||||
|
||||
md-inline-grid-icon[icon=facebook] {
|
||||
background-image: url('data:image/svg+xml;charset=utf-8;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iNDhweCINCgkgaGVpZ2h0PSI0OHB4IiB2aWV3Qm94PSIwIDAgNDggNDgiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDQ4IDQ4IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxnIGlkPSJIZWFkZXIiPg0KCTxnPg0KCQk8cmVjdCB4PSItODM4IiB5PSItMzI1NiIgZmlsbD0ibm9uZSIgd2lkdGg9IjE0MDAiIGhlaWdodD0iMzYwMCIvPg0KCTwvZz4NCjwvZz4NCjxnIGlkPSJMYWJlbCI+DQo8L2c+DQo8ZyBpZD0iSWNvbiI+DQoJPGc+DQoJCTxnPg0KCQkJPHBhdGggZmlsbD0iIzdkN2Q3ZCIgZD0iTTQwLDRIOEM1LjgsNCw0LDUuOCw0LDhsMCwzMmMwLDIuMiwxLjgsNCw0LDRoMzJjMi4yLDAsNC0xLjgsNC00VjhDNDQsNS44LDQyLjIsNCw0MCw0eiBNMzgsOHY2aC00Yy0xLjEsMC0yLDAuOS0yLDJ2NA0KCQkJCWg2djZoLTZ2MTRoLTZWMjZoLTR2LTZoNHYtNWMwLTMuOSwzLjEtNyw3LTdIMzh6Ii8+DQoJCTwvZz4NCgkJPGc+DQoJCQk8cmVjdCBmaWxsPSJub25lIiB3aWR0aD0iNDgiIGhlaWdodD0iNDgiLz4NCgkJPC9nPg0KCTwvZz4NCjwvZz4NCjxnIGlkPSJHcmlkIiBkaXNwbGF5PSJub25lIj4NCgk8ZyBkaXNwbGF5PSJpbmxpbmUiPg0KCQk8bGluZSBmaWxsPSJub25lIiBzdHJva2U9IiMwMEU1RkYiIHN0cm9rZS13aWR0aD0iMC4xIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHgxPSI0MiIgeTE9Ii0zMjU2IiB4Mj0iNDIiIHkyPSIyOTYiLz4NCgk8L2c+DQo8L2c+DQo8L3N2Zz4NCg==');
|
||||
}
|
||||
|
||||
md-inline-grid-icon[icon=twitter] {
|
||||
background-image: url('data:image/svg+xml;charset=utf-8;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iNDhweCINCgkgaGVpZ2h0PSI0OHB4IiB2aWV3Qm94PSIwIDAgNDggNDgiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDQ4IDQ4IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxnIGlkPSJIZWFkZXIiPg0KCTxnPg0KCQk8cmVjdCB4PSItODM4IiB5PSItOTUyIiBmaWxsPSJub25lIiB3aWR0aD0iMTQwMCIgaGVpZ2h0PSIzNjAwIi8+DQoJPC9nPg0KPC9nPg0KPGcgaWQ9IkxhYmVsIj4NCjwvZz4NCjxnIGlkPSJJY29uIj4NCgk8Zz4NCgkJPGc+DQoJCQk8cGF0aCBmaWxsPSIjN2Q3ZDdkIiBkPSJNNDAsNEg4QzUuOCw0LDQsNS44LDQsOGwwLDMyYzAsMi4yLDEuOCw0LDQsNGgzMmMyLjIsMCw0LTEuOCw0LTRWOEM0NCw1LjgsNDIuMiw0LDQwLDR6IE0zNS40LDE4LjcNCgkJCQljLTAuMSw5LjItNiwxNS42LTE0LjgsMTZjLTMuNiwwLjItNi4zLTEtOC42LTIuNWMyLjcsMC40LDYtMC42LDcuOC0yLjJjLTIuNi0wLjMtNC4yLTEuNi00LjktMy44YzAuOCwwLjEsMS42LDAuMSwyLjMtMC4xDQoJCQkJYy0yLjQtMC44LTQuMS0yLjMtNC4yLTUuM2MwLjcsMC4zLDEuNCwwLjYsMi4zLDAuNmMtMS44LTEtMy4xLTQuNy0xLjYtNy4yYzIuNiwyLjksNS44LDUuMywxMSw1LjZjLTEuMy01LjYsNi4xLTguNiw5LjItNC45DQoJCQkJYzEuMy0wLjMsMi40LTAuOCwzLjQtMS4zYy0wLjQsMS4zLTEuMiwyLjItMi4yLDIuOWMxLjEtMC4xLDIuMS0wLjQsMi45LTAuOEMzNy41LDE2LjksMzYuNCwxNy45LDM1LjQsMTguN3oiLz4NCgkJPC9nPg0KCQk8Zz4NCgkJCTxyZWN0IGZpbGw9Im5vbmUiIHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCIvPg0KCQk8L2c+DQoJPC9nPg0KPC9nPg0KPGcgaWQ9IkdyaWQiIGRpc3BsYXk9Im5vbmUiPg0KCTxnIGRpc3BsYXk9ImlubGluZSI+DQoJCTxsaW5lIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwRTVGRiIgc3Ryb2tlLXdpZHRoPSIwLjEiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgeDE9IjQyIiB5MT0iLTk1MiIgeDI9IjQyIiB5Mj0iMjYwMCIvPg0KCTwvZz4NCjwvZz4NCjwvc3ZnPg0K');
|
||||
}
|
||||
|
||||
|
||||
|
||||
84
UI/WebServerResources/scss/vendors/angular-material/components/button/button-theme.scss
vendored
Normal file
84
UI/WebServerResources/scss/vendors/angular-material/components/button/button-theme.scss
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
$button-border-radius: 3px !default;
|
||||
$button-fab-border-radius: 50% !default;
|
||||
|
||||
.md-button.md-THEME_NAME-theme {
|
||||
border-radius: $button-border-radius;
|
||||
|
||||
&:not([disabled]) {
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: '{{background-500-0.2}}';
|
||||
}
|
||||
}
|
||||
|
||||
&.md-primary {
|
||||
color: '{{primary-color}}';
|
||||
&.md-raised,
|
||||
&.md-fab {
|
||||
color: '{{primary-contrast}}';
|
||||
background-color: '{{primary-color}}';
|
||||
&:not([disabled]) {
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: '{{primary-600}}';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.md-fab {
|
||||
border-radius: $button-fab-border-radius;
|
||||
}
|
||||
|
||||
&.md-raised,
|
||||
&.md-fab {
|
||||
color: '{{background-contrast}}';
|
||||
background-color: '{{background-500-0.185}}';
|
||||
&:not([disabled]) {
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: '{{background-500-0.3}}';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.md-warn {
|
||||
color: '{{warn-color}}';
|
||||
|
||||
&.md-raised,
|
||||
&.md-fab {
|
||||
color: '{{warn-contrast}}';
|
||||
background-color: '{{warn-color}}';
|
||||
&:not([disabled]) {
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: '{{warn-700}}';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.md-accent {
|
||||
color: '{{accent-color}}';
|
||||
|
||||
&.md-raised,
|
||||
&.md-fab {
|
||||
color: '{{accent-contrast}}';
|
||||
background-color: '{{accent-color}}';
|
||||
&:not([disabled]) {
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: '{{accent-700}}';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&[disabled],
|
||||
&.md-raised[disabled],
|
||||
&.md-fab[disabled] {
|
||||
color: '{{foreground-3}}';
|
||||
background-color: transparent;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
87
UI/WebServerResources/scss/vendors/angular-material/components/button/button.js
vendored
Normal file
87
UI/WebServerResources/scss/vendors/angular-material/components/button/button.js
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc module
|
||||
* @name material.components.button
|
||||
* @description
|
||||
*
|
||||
* Button
|
||||
*/
|
||||
angular.module('material.components.button', [
|
||||
'material.core'
|
||||
])
|
||||
.directive('mdButton', MdButtonDirective);
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name mdButton
|
||||
* @module material.components.button
|
||||
*
|
||||
* @restrict E
|
||||
*
|
||||
* @description
|
||||
* `<md-button>` is a button directive with optional ink ripples (default enabled).
|
||||
*
|
||||
* If you supply a `href` or `ng-href` attribute, it will become an `<a>` element. Otherwise, it will
|
||||
* become a `<button>` element.
|
||||
*
|
||||
* @param {boolean=} md-no-ink If present, disable ripple ink effects.
|
||||
* @param {expression=} ng-disabled En/Disable based on the expression
|
||||
* @param {string=} aria-label Adds alternative text to button for accessibility, useful for icon buttons.
|
||||
* If no default text is found, a warning will be logged.
|
||||
*
|
||||
* @usage
|
||||
* <hljs lang="html">
|
||||
* <md-button>
|
||||
* Button
|
||||
* </md-button>
|
||||
* <md-button href="http://google.com" class="md-button-colored">
|
||||
* I'm a link
|
||||
* </md-button>
|
||||
* <md-button ng-disabled="true" class="md-colored">
|
||||
* I'm a disabled button
|
||||
* </md-button>
|
||||
* </hljs>
|
||||
*/
|
||||
function MdButtonDirective($mdInkRipple, $mdTheming, $mdAria) {
|
||||
|
||||
return {
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
transclude: true,
|
||||
template: getTemplate,
|
||||
link: postLink
|
||||
};
|
||||
|
||||
function isAnchor(attr) {
|
||||
return angular.isDefined(attr.href) || angular.isDefined(attr.ngHref);
|
||||
}
|
||||
|
||||
function getTemplate(element, attr) {
|
||||
return isAnchor(attr) ?
|
||||
'<a class="md-button" ng-transclude></a>' :
|
||||
'<button class="md-button" ng-transclude></button>';
|
||||
}
|
||||
|
||||
function postLink(scope, element, attr) {
|
||||
var node = element[0];
|
||||
$mdTheming(element);
|
||||
$mdInkRipple.attachButtonBehavior(scope, element);
|
||||
|
||||
var elementHasText = node.textContent.trim();
|
||||
if (!elementHasText) {
|
||||
$mdAria.expect(element, 'aria-label');
|
||||
}
|
||||
|
||||
// For anchor elements, we have to set tabindex manually when the
|
||||
// element is disabled
|
||||
if (isAnchor(attr) && angular.isDefined(attr.ngDisabled) ) {
|
||||
scope.$watch(attr.ngDisabled, function(isDisabled) {
|
||||
element.attr('tabindex', isDisabled ? -1 : 0);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
})();
|
||||
173
UI/WebServerResources/scss/vendors/angular-material/components/button/button.scss
vendored
Normal file
173
UI/WebServerResources/scss/vendors/angular-material/components/button/button.scss
vendored
Normal file
@@ -0,0 +1,173 @@
|
||||
$button-line-height: 25px !default;
|
||||
$button-padding: 2px 6px 3px !default;
|
||||
|
||||
// Fab buttons
|
||||
$button-fab-width: 56px !default;
|
||||
$button-fab-height: 56px !default;
|
||||
$button-fab-padding: 16px !default;
|
||||
|
||||
$button-fab-toast-offset: $button-fab-height * 0.75;
|
||||
|
||||
/**
|
||||
* Position a FAB button.
|
||||
*/
|
||||
@mixin fab-position($spot, $top: auto, $right: auto, $bottom: auto, $left: auto) {
|
||||
&.md-fab-#{$spot} {
|
||||
top: $top;
|
||||
right: $right;
|
||||
bottom: $bottom;
|
||||
left: $left;
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
.md-button {
|
||||
|
||||
user-select: none;
|
||||
position: relative; //for child absolute-positioned <canvas>
|
||||
|
||||
outline: none;
|
||||
border: 0;
|
||||
padding: 6px;
|
||||
margin: 0;
|
||||
background: transparent;
|
||||
white-space: nowrap;
|
||||
|
||||
text-align: center;
|
||||
|
||||
// Always uppercase buttons
|
||||
text-transform: uppercase;
|
||||
font-weight: 500;
|
||||
font-style: inherit;
|
||||
font-variant: inherit;
|
||||
font-size: inherit;
|
||||
font-family: inherit;
|
||||
line-height: inherit;
|
||||
text-decoration: none;
|
||||
|
||||
cursor: pointer;
|
||||
overflow: hidden; // for ink containment
|
||||
|
||||
transition: box-shadow $swift-ease-out-duration $swift-ease-out-timing-function,
|
||||
background-color $swift-ease-out-duration $swift-ease-out-timing-function,
|
||||
transform $swift-ease-out-duration $swift-ease-out-timing-function;
|
||||
|
||||
&.ng-hide {
|
||||
transition: none;
|
||||
}
|
||||
;
|
||||
|
||||
&.md-cornered {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
&.md-icon {
|
||||
padding: 0;
|
||||
background: none;
|
||||
}
|
||||
|
||||
&.md-raised {
|
||||
transform: translate3d(0, 0, 0);
|
||||
|
||||
&:not([disabled]) {
|
||||
@extend .md-shadow-bottom-z-1;
|
||||
}
|
||||
}
|
||||
|
||||
&.md-fab {
|
||||
|
||||
@include fab-position(bottom-right, auto, ($button-fab-width - $button-fab-padding)/2, ($button-fab-height - $button-fab-padding)/2, auto);
|
||||
@include fab-position(bottom-left, auto, auto, ($button-fab-height - $button-fab-padding)/2, ($button-fab-width - $button-fab-padding)/2);
|
||||
@include fab-position(top-right, ($button-fab-height - $button-fab-padding)/2, ($button-fab-width - $button-fab-padding)/2, auto, auto);
|
||||
@include fab-position(top-left, ($button-fab-height - $button-fab-padding)/2, auto, auto, ($button-fab-width - $button-fab-padding)/2);
|
||||
|
||||
z-index: $z-index-fab;
|
||||
|
||||
width: $button-fab-width;
|
||||
height: $button-fab-height;
|
||||
|
||||
border-radius: 50%;
|
||||
|
||||
@extend .md-shadow-bottom-z-1;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
|
||||
transform: translate3d(0,0,0);
|
||||
|
||||
transition: 0.2s linear;
|
||||
transition-property: transform, box-shadow;
|
||||
|
||||
md-icon {
|
||||
line-height: $button-fab-height;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&:not([disabled]) {
|
||||
&.md-raised,
|
||||
&.md-fab {
|
||||
&:focus,
|
||||
&:hover {
|
||||
transform: translate3d(0, -1px, 0);
|
||||
@extend .md-shadow-bottom-z-2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.md-toast-open-top {
|
||||
.md-button.md-fab-top-left,
|
||||
.md-button.md-fab-top-right {
|
||||
transform: translate3d(0, $button-fab-toast-offset, 0);
|
||||
&:not([disabled]) {
|
||||
&:focus,
|
||||
&:hover {
|
||||
transform: translate3d(0, $button-fab-toast-offset - 1, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.md-toast-open-bottom {
|
||||
.md-button.md-fab-bottom-left,
|
||||
.md-button.md-fab-bottom-right {
|
||||
transform: translate3d(0, -$button-fab-toast-offset, 0);
|
||||
&:not([disabled]) {
|
||||
&:focus,
|
||||
&:hover {
|
||||
transform: translate3d(0, -$button-fab-toast-offset - 1, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.md-button-group {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
}
|
||||
.md-button-group > .md-button {
|
||||
flex: 1;
|
||||
|
||||
display: block;
|
||||
|
||||
overflow: hidden;
|
||||
|
||||
width: 0;
|
||||
|
||||
border-width: 1px 0px 1px 1px;
|
||||
border-radius: 0;
|
||||
|
||||
text-align: center;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
||||
&:first-child {
|
||||
border-radius: 2px 0px 0px 2px;
|
||||
}
|
||||
&:last-child {
|
||||
border-right-width: 1px;
|
||||
border-radius: 0px 2px 2px 0px;
|
||||
}
|
||||
}
|
||||
91
UI/WebServerResources/scss/vendors/angular-material/components/button/button.spec.js
vendored
Normal file
91
UI/WebServerResources/scss/vendors/angular-material/components/button/button.spec.js
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
describe('md-button', function() {
|
||||
|
||||
beforeEach(TestUtil.mockRaf);
|
||||
beforeEach(module('material.components.button'));
|
||||
|
||||
it('should convert attributes on an md-button to attributes on the generated button', inject(function($compile, $rootScope) {
|
||||
var button = $compile('<md-button hide hide-sm></md-button>')($rootScope);
|
||||
$rootScope.$apply();
|
||||
expect(button[0].hasAttribute('hide')).toBe(true);
|
||||
expect(button[0].hasAttribute('hide-sm')).toBe(true);
|
||||
}));
|
||||
|
||||
it('should only have one ripple container when a custom ripple color is set', inject(function ($compile, $rootScope, $timeout) {
|
||||
var button = $compile('<md-button md-ink-ripple="#f00">button</md-button>')($rootScope);
|
||||
var scope = button.eq(0).scope();
|
||||
scope._onInput({ isFirst: true, eventType: Hammer.INPUT_START, center: { x: 0, y: 0 } });
|
||||
expect(button[0].getElementsByClassName('md-ripple-container').length).toBe(1);
|
||||
}));
|
||||
|
||||
|
||||
it('should expect an aria-label if element has no text', inject(function($compile, $rootScope, $log) {
|
||||
spyOn($log, 'warn');
|
||||
var button = $compile('<md-button><md-icon></md-icon></md-button>')($rootScope);
|
||||
$rootScope.$apply();
|
||||
expect($log.warn).toHaveBeenCalled();
|
||||
|
||||
$log.warn.reset();
|
||||
button = $compile('<md-button aria-label="something"><md-icon></md-icon></md-button>')($rootScope);
|
||||
$rootScope.$apply();
|
||||
expect($log.warn).not.toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
|
||||
describe('with href or ng-href', function() {
|
||||
|
||||
it('should be anchor if href attr', inject(function($compile, $rootScope) {
|
||||
var button = $compile('<md-button href="/link">')($rootScope.$new());
|
||||
$rootScope.$apply();
|
||||
expect(button[0].tagName.toLowerCase()).toEqual('a');
|
||||
}));
|
||||
|
||||
it('should be anchor if ng-href attr', inject(function($compile, $rootScope) {
|
||||
var button = $compile('<md-button ng-href="/link">')($rootScope.$new());
|
||||
$rootScope.$apply();
|
||||
expect(button[0].tagName.toLowerCase()).toEqual('a');
|
||||
}));
|
||||
|
||||
it('should be button otherwise', inject(function($compile, $rootScope) {
|
||||
var button = $compile('<md-button>')($rootScope.$new());
|
||||
$rootScope.$apply();
|
||||
expect(button[0].tagName.toLowerCase()).toEqual('button');
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('with ng-disabled', function() {
|
||||
|
||||
it('should not set `tabindex` when used without anchor attributes', inject(function ($compile, $rootScope, $timeout) {
|
||||
var scope = angular.extend( $rootScope.$new(), { isDisabled : true } );
|
||||
var button = $compile('<md-button ng-disabled="isDisabled">button</md-button>')(scope);
|
||||
$rootScope.$apply();
|
||||
|
||||
expect(button[0].hasAttribute('tabindex')).toBe(false);
|
||||
}));
|
||||
|
||||
it('should set `tabindex == -1` when used with href', inject(function ($compile, $rootScope, $timeout) {
|
||||
var scope = angular.extend( $rootScope.$new(), { isDisabled : true } );
|
||||
var button = $compile('<md-button ng-disabled="isDisabled" href="#nowhere">button</md-button>')(scope);
|
||||
|
||||
$rootScope.$apply();
|
||||
expect(button.attr('tabindex')).toBe("-1");
|
||||
|
||||
$rootScope.$apply(function(){
|
||||
scope.isDisabled = false;
|
||||
});
|
||||
expect(button.attr('tabindex')).toBe("0");
|
||||
|
||||
}));
|
||||
|
||||
it('should set `tabindex == -1` when used with ng-href', inject(function ($compile, $rootScope, $timeout) {
|
||||
var scope = angular.extend( $rootScope.$new(), { isDisabled : true, url : "http://material.angularjs.org" });
|
||||
var button = $compile('<md-button ng-disabled="isDisabled" ng-href="url">button</md-button>')(scope);
|
||||
$rootScope.$apply();
|
||||
|
||||
expect(button.attr('tabindex')).toBe("-1");
|
||||
}));
|
||||
|
||||
})
|
||||
|
||||
});
|
||||
53
UI/WebServerResources/scss/vendors/angular-material/components/button/demoBasicUsage/index.html
vendored
Normal file
53
UI/WebServerResources/scss/vendors/angular-material/components/button/demoBasicUsage/index.html
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
|
||||
<div ng-controller="AppCtrl">
|
||||
<md-content >
|
||||
|
||||
<section layout="row" layout-sm="column" layout-align="center center">
|
||||
<md-button>{{title1}}</md-button>
|
||||
<md-button md-no-ink class="md-primary">Primary (md-noink)</md-button>
|
||||
<md-button ng-disabled="true" class="md-primary">Disabled</md-button>
|
||||
<md-button class="md-warn">{{title4}}</md-button>
|
||||
</section>
|
||||
|
||||
<section layout="row" layout-sm="column" layout-align="center center">
|
||||
<md-button class="md-raised">Button</md-button>
|
||||
<md-button class="md-raised md-primary">Primary</md-button>
|
||||
<md-button ng-disabled="true" class="md-raised md-primary">Disabled</md-button>
|
||||
<md-button class="md-raised md-warn">Warn</md-button>
|
||||
<div class="label">raised</div>
|
||||
</section>
|
||||
|
||||
<section layout="row" layout-sm="column" layout-align="center center">
|
||||
<md-button class="md-fab" aria-label="Time">
|
||||
<md-icon icon="/img/icons/ic_access_time_24px.svg" style="width: 24px; height: 24px;"></md-icon>
|
||||
</md-button>
|
||||
|
||||
<md-button class="md-fab" aria-label="New document">
|
||||
<md-icon icon="/img/icons/ic_insert_drive_file_24px.svg" style="width: 24px; height: 24px;"></md-icon>
|
||||
</md-button>
|
||||
|
||||
<md-button class="md-fab" ng-disabled="true" aria-label="Comment">
|
||||
<md-icon icon="/img/icons/ic_comment_24px.svg" style="width: 24px; height: 24px;"></md-icon>
|
||||
</md-button>
|
||||
|
||||
<md-button class="md-fab md-primary" md-theme="cyan" aria-label="Profile">
|
||||
<md-icon icon="/img/icons/ic_people_24px.svg" style="width: 24px; height: 24px;"></md-icon>
|
||||
</md-button>
|
||||
<div class="label">FAB</div>
|
||||
</section>
|
||||
|
||||
<section layout="row" layout-sm="column" layout-align="center center">
|
||||
<md-button ng-href="{{googleUrl}}" target="_blank">Go to Google</md-button>
|
||||
<md-button>RSVP</md-button>
|
||||
</section>
|
||||
|
||||
<section layout="row" layout-sm="column" layout-align="center center">
|
||||
<md-button class="md-primary md-hue-1">Primary Hue 1</md-button>
|
||||
<md-button class="md-warn md-raised md-hue-2">Warn Hue 2</md-button>
|
||||
<md-button class="md-accent">Accent</md-button>
|
||||
<md-button class="md-accent md-raised md-hue-3">Accent Hue 3</md-button>
|
||||
<div class="label">Themed</div>
|
||||
</section>
|
||||
|
||||
</md-content>
|
||||
</div>
|
||||
11
UI/WebServerResources/scss/vendors/angular-material/components/button/demoBasicUsage/script.js
vendored
Normal file
11
UI/WebServerResources/scss/vendors/angular-material/components/button/demoBasicUsage/script.js
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
angular.module('buttonsDemo1', ['ngMaterial'])
|
||||
|
||||
.controller('AppCtrl', function($scope) {
|
||||
$scope.title1 = 'Button';
|
||||
$scope.title4 = 'Warn';
|
||||
$scope.isDisabled = true;
|
||||
|
||||
$scope.googleUrl = 'http://google.com';
|
||||
|
||||
});
|
||||
30
UI/WebServerResources/scss/vendors/angular-material/components/button/demoBasicUsage/style.css
vendored
Normal file
30
UI/WebServerResources/scss/vendors/angular-material/components/button/demoBasicUsage/style.css
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
|
||||
/** From vulcanized demo **/
|
||||
|
||||
section {
|
||||
background: #f7f7f7;
|
||||
border-radius: 3px;
|
||||
text-align: center;
|
||||
margin: 1em;
|
||||
position: relative !important;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
md-content {
|
||||
margin-right: 7px;
|
||||
}
|
||||
section .md-button:not(.md-fab) {
|
||||
min-width: 10em;
|
||||
}
|
||||
section .md-button {
|
||||
display: block;
|
||||
margin: 1em;
|
||||
line-height: 25px;
|
||||
}
|
||||
.label {
|
||||
position: absolute;
|
||||
bottom: 5px;
|
||||
left: 7px;
|
||||
color: #ccc;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
9
UI/WebServerResources/scss/vendors/angular-material/components/card/card-theme.scss
vendored
Normal file
9
UI/WebServerResources/scss/vendors/angular-material/components/card/card-theme.scss
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
$card-border-radius: 2px !default;
|
||||
|
||||
md-card.md-THEME_NAME-theme {
|
||||
border-radius: $card-border-radius;
|
||||
|
||||
.md-card-image {
|
||||
border-radius: $card-border-radius $card-border-radius 0 0;
|
||||
}
|
||||
}
|
||||
51
UI/WebServerResources/scss/vendors/angular-material/components/card/card.js
vendored
Normal file
51
UI/WebServerResources/scss/vendors/angular-material/components/card/card.js
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc module
|
||||
* @name material.components.card
|
||||
*
|
||||
* @description
|
||||
* Card components.
|
||||
*/
|
||||
angular.module('material.components.card', [
|
||||
'material.core'
|
||||
])
|
||||
.directive('mdCard', mdCardDirective);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name mdCard
|
||||
* @module material.components.card
|
||||
*
|
||||
* @restrict E
|
||||
*
|
||||
* @description
|
||||
* The `<md-card>` directive is a container element used within `<md-content>` containers.
|
||||
*
|
||||
* Cards have constant width and variable heights; where the maximum height is limited to what can
|
||||
* fit within a single view on a platform, but it can temporarily expand as needed
|
||||
*
|
||||
* @usage
|
||||
* <hljs lang="html">
|
||||
* <md-card>
|
||||
* <img src="img/washedout.png" class="md-card-image">
|
||||
* <h2>Paracosm</h2>
|
||||
* <p>
|
||||
* The titles of Washed Out's breakthrough song and the first single from Paracosm share the * two most important words in Ernest Greene's musical language: feel it. It's a simple request, as well...
|
||||
* </p>
|
||||
* </md-card>
|
||||
* </hljs>
|
||||
*
|
||||
*/
|
||||
function mdCardDirective($mdTheming) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
link: function($scope, $element, $attr) {
|
||||
$mdTheming($element);
|
||||
}
|
||||
};
|
||||
}
|
||||
})();
|
||||
20
UI/WebServerResources/scss/vendors/angular-material/components/card/card.scss
vendored
Normal file
20
UI/WebServerResources/scss/vendors/angular-material/components/card/card.scss
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
$card-margin: 8px !default;
|
||||
$card-box-shadow: $whiteframe-shadow-z1 !default;
|
||||
|
||||
md-card {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
box-shadow: $card-box-shadow;
|
||||
|
||||
> img {
|
||||
order: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
md-card-content {
|
||||
order: 1;
|
||||
margin: $card-margin;
|
||||
}
|
||||
}
|
||||
16
UI/WebServerResources/scss/vendors/angular-material/components/card/card.spec.js
vendored
Normal file
16
UI/WebServerResources/scss/vendors/angular-material/components/card/card.spec.js
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
describe('mdCard directive', function() {
|
||||
|
||||
beforeEach(module('material.components.card'));
|
||||
|
||||
it('should have the default theme class when the md-theme attribute is not defined', inject(function($compile, $rootScope) {
|
||||
var card = $compile('<md-card></md-card>')($rootScope.$new());
|
||||
$rootScope.$apply();
|
||||
expect(card.hasClass('md-default-theme')).toBe(true);
|
||||
}));
|
||||
|
||||
it('should have the correct theme class when the md-theme attribute is defined', inject(function($compile, $rootScope) {
|
||||
var card = $compile('<md-card md-theme="green"></md-card>')($rootScope.$new());
|
||||
$rootScope.$apply();
|
||||
expect(card.hasClass('md-green-theme')).toBe(true);
|
||||
}));
|
||||
});
|
||||
41
UI/WebServerResources/scss/vendors/angular-material/components/card/demoBasicUsage/index.html
vendored
Normal file
41
UI/WebServerResources/scss/vendors/angular-material/components/card/demoBasicUsage/index.html
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
|
||||
<div ng-controller="AppCtrl">
|
||||
|
||||
<md-content>
|
||||
|
||||
<md-card>
|
||||
<img src="img/washedout.png" alt="Washed Out">
|
||||
<md-card-content>
|
||||
<h2>Paracosm</h2>
|
||||
<p>
|
||||
The titles of Washed Out's breakthrough song and the first single from Paracosm share the
|
||||
two most important words in Ernest Greene's musical language: feel it. It's a simple request, as well...
|
||||
</p>
|
||||
</md-card-content>
|
||||
</md-card>
|
||||
|
||||
<md-card>
|
||||
<img src="img/washedout.png" alt="Washed Out">
|
||||
<md-card-content>
|
||||
<h2>Paracosm</h2>
|
||||
<p>
|
||||
The titles of Washed Out's breakthrough song and the first single from Paracosm share the
|
||||
two most important words in Ernest Greene's musical language: feel it. It's a simple request, as well...
|
||||
</p>
|
||||
</md-card-content>
|
||||
</md-card>
|
||||
|
||||
<md-card>
|
||||
<img src="img/washedout.png" alt="Washed Out">
|
||||
<md-card-content>
|
||||
<h2>Paracosm</h2>
|
||||
<p>
|
||||
The titles of Washed Out's breakthrough song and the first single from Paracosm share the
|
||||
two most important words in Ernest Greene's musical language: feel it. It's a simple request, as well...
|
||||
</p>
|
||||
</md-card-content>
|
||||
</md-card>
|
||||
|
||||
|
||||
</md-content>
|
||||
</div>
|
||||
6
UI/WebServerResources/scss/vendors/angular-material/components/card/demoBasicUsage/script.js
vendored
Normal file
6
UI/WebServerResources/scss/vendors/angular-material/components/card/demoBasicUsage/script.js
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
angular.module('cardDemo1', ['ngMaterial'])
|
||||
|
||||
.controller('AppCtrl', function($scope) {
|
||||
|
||||
});
|
||||
4
UI/WebServerResources/scss/vendors/angular-material/components/card/demoBasicUsage/style.css
vendored
Normal file
4
UI/WebServerResources/scss/vendors/angular-material/components/card/demoBasicUsage/style.css
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
md-card {
|
||||
min-height: 150px;
|
||||
}
|
||||
73
UI/WebServerResources/scss/vendors/angular-material/components/checkbox/checkbox-theme.scss
vendored
Normal file
73
UI/WebServerResources/scss/vendors/angular-material/components/checkbox/checkbox-theme.scss
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
md-checkbox.md-THEME_NAME-theme {
|
||||
|
||||
.md-ripple {
|
||||
color: '{{accent-600}}';
|
||||
}
|
||||
&.md-checked .md-ripple {
|
||||
color: '{{background-600}}';
|
||||
}
|
||||
|
||||
.md-icon {
|
||||
border-color: '{{foreground-2}}';
|
||||
}
|
||||
&.md-checked .md-icon {
|
||||
background-color: '{{accent-color-0.87}}';
|
||||
}
|
||||
|
||||
&.md-checked .md-icon:after {
|
||||
border-color: '{{background-200}}';
|
||||
}
|
||||
|
||||
&:not([disabled]) {
|
||||
&.md-primary {
|
||||
.md-ripple {
|
||||
color: '{{primary-600}}';
|
||||
}
|
||||
&.md-checked .md-ripple {
|
||||
color: '{{background-600}}';
|
||||
}
|
||||
|
||||
.md-icon {
|
||||
border-color: '{{foreground-2}}';
|
||||
}
|
||||
&.md-checked .md-icon {
|
||||
background-color: '{{primary-color-0.87}}';
|
||||
}
|
||||
|
||||
&.md-checked .md-icon:after {
|
||||
border-color: '{{background-200}}';
|
||||
}
|
||||
}
|
||||
|
||||
&.md-warn {
|
||||
.md-ripple {
|
||||
color: '{{warn-600}}';
|
||||
}
|
||||
&.md-checked .md-ripple {
|
||||
color: '{{background-600}}';
|
||||
}
|
||||
|
||||
.md-icon {
|
||||
border-color: '{{foreground-2}}';
|
||||
}
|
||||
&.md-checked .md-icon {
|
||||
background-color: '{{warn-color-0.87}}';
|
||||
}
|
||||
|
||||
&.md-checked .md-icon:after {
|
||||
border-color: '{{background-200}}';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&[disabled] {
|
||||
.md-icon {
|
||||
border-color: '{{foreground-3}}';
|
||||
}
|
||||
|
||||
&.md-checked .md-icon {
|
||||
background-color: '{{foreground-3}}';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
126
UI/WebServerResources/scss/vendors/angular-material/components/checkbox/checkbox.js
vendored
Normal file
126
UI/WebServerResources/scss/vendors/angular-material/components/checkbox/checkbox.js
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc module
|
||||
* @name material.components.checkbox
|
||||
* @description Checkbox module!
|
||||
*/
|
||||
angular.module('material.components.checkbox', [
|
||||
'material.core'
|
||||
])
|
||||
.directive('mdCheckbox', MdCheckboxDirective);
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name mdCheckbox
|
||||
* @module material.components.checkbox
|
||||
* @restrict E
|
||||
*
|
||||
* @description
|
||||
* The checkbox directive is used like the normal [angular checkbox](https://docs.angularjs.org/api/ng/input/input%5Bcheckbox%5D).
|
||||
*
|
||||
* @param {string} ng-model Assignable angular expression to data-bind to.
|
||||
* @param {string=} name Property name of the form under which the control is published.
|
||||
* @param {expression=} ng-true-value The value to which the expression should be set when selected.
|
||||
* @param {expression=} ng-false-value The value to which the expression should be set when not selected.
|
||||
* @param {string=} ng-change Angular expression to be executed when input changes due to user interaction with the input element.
|
||||
* @param {boolean=} md-no-ink Use of attribute indicates use of ripple ink effects
|
||||
* @param {string=} aria-label Adds label to checkbox for accessibility.
|
||||
* Defaults to checkbox's text. If no default text is found, a warning will be logged.
|
||||
*
|
||||
* @usage
|
||||
* <hljs lang="html">
|
||||
* <md-checkbox ng-model="isChecked" aria-label="Finished?">
|
||||
* Finished ?
|
||||
* </md-checkbox>
|
||||
*
|
||||
* <md-checkbox md-no-ink ng-model="hasInk" aria-label="No Ink Effects">
|
||||
* No Ink Effects
|
||||
* </md-checkbox>
|
||||
*
|
||||
* <md-checkbox ng-disabled="true" ng-model="isDisabled" aria-label="Disabled">
|
||||
* Disabled
|
||||
* </md-checkbox>
|
||||
*
|
||||
* </hljs>
|
||||
*
|
||||
*/
|
||||
function MdCheckboxDirective(inputDirective, $mdInkRipple, $mdAria, $mdConstant, $mdTheming, $mdUtil) {
|
||||
inputDirective = inputDirective[0];
|
||||
var CHECKED_CSS = 'md-checked';
|
||||
|
||||
return {
|
||||
restrict: 'E',
|
||||
transclude: true,
|
||||
require: '?ngModel',
|
||||
template:
|
||||
'<div class="md-container" md-ink-ripple md-ink-ripple-checkbox>' +
|
||||
'<div class="md-icon"></div>' +
|
||||
'</div>' +
|
||||
'<div ng-transclude class="md-label"></div>',
|
||||
compile: compile
|
||||
};
|
||||
|
||||
// **********************************************************
|
||||
// Private Methods
|
||||
// **********************************************************
|
||||
|
||||
function compile (tElement, tAttrs) {
|
||||
|
||||
tAttrs.type = 'checkbox';
|
||||
tAttrs.tabIndex = 0;
|
||||
tElement.attr('role', tAttrs.type);
|
||||
|
||||
return function postLink(scope, element, attr, ngModelCtrl) {
|
||||
ngModelCtrl = ngModelCtrl || $mdUtil.fakeNgModel();
|
||||
var checked = false;
|
||||
$mdTheming(element);
|
||||
|
||||
$mdAria.expectWithText(tElement, 'aria-label');
|
||||
|
||||
// Reuse the original input[type=checkbox] directive from Angular core.
|
||||
// This is a bit hacky as we need our own event listener and own render
|
||||
// function.
|
||||
inputDirective.link.pre(scope, {
|
||||
on: angular.noop,
|
||||
0: {}
|
||||
}, attr, [ngModelCtrl]);
|
||||
|
||||
// Used by switch. in Switch, we don't want click listeners; we have more granular
|
||||
// touchup/touchdown listening.
|
||||
if (!attr.mdNoClick) {
|
||||
element.on('click', listener);
|
||||
}
|
||||
element.on('keypress', keypressHandler);
|
||||
ngModelCtrl.$render = render;
|
||||
|
||||
function keypressHandler(ev) {
|
||||
if(ev.which === $mdConstant.KEY_CODE.SPACE) {
|
||||
ev.preventDefault();
|
||||
listener(ev);
|
||||
}
|
||||
}
|
||||
function listener(ev) {
|
||||
if (element[0].hasAttribute('disabled')) return;
|
||||
|
||||
scope.$apply(function() {
|
||||
checked = !checked;
|
||||
ngModelCtrl.$setViewValue(checked, ev && ev.type);
|
||||
ngModelCtrl.$render();
|
||||
});
|
||||
}
|
||||
|
||||
function render() {
|
||||
checked = ngModelCtrl.$viewValue;
|
||||
if(checked) {
|
||||
element.addClass(CHECKED_CSS);
|
||||
} else {
|
||||
element.removeClass(CHECKED_CSS);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
||||
91
UI/WebServerResources/scss/vendors/angular-material/components/checkbox/checkbox.scss
vendored
Normal file
91
UI/WebServerResources/scss/vendors/angular-material/components/checkbox/checkbox.scss
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
$checkbox-width: 18px !default;
|
||||
$checkbox-height: $checkbox-width !default;
|
||||
|
||||
md-checkbox {
|
||||
display: block;
|
||||
margin: 15px;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
user-select: none;
|
||||
|
||||
.md-container {
|
||||
position: relative;
|
||||
top: 4px;
|
||||
display: inline-block;
|
||||
width: $checkbox-width;
|
||||
height: $checkbox-height;
|
||||
|
||||
&:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -10px;
|
||||
right: -10px;
|
||||
bottom: -10px;
|
||||
left: -10px;
|
||||
}
|
||||
|
||||
.md-ripple-container {
|
||||
position: absolute;
|
||||
display: block;
|
||||
width: auto;
|
||||
height: auto;
|
||||
left: -15px;
|
||||
top: -15px;
|
||||
right: -15px;
|
||||
bottom: -15px;
|
||||
}
|
||||
}
|
||||
|
||||
// unchecked
|
||||
.md-icon {
|
||||
transition: 240ms;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: $checkbox-width;
|
||||
height: $checkbox-height;
|
||||
border: 2px solid;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
&.md-checked .md-icon {
|
||||
border: none;
|
||||
}
|
||||
|
||||
// disabled
|
||||
&[disabled] {
|
||||
cursor: no-drop;
|
||||
}
|
||||
|
||||
// focus
|
||||
&:focus .md-label:not(:empty) {
|
||||
border-color: black;
|
||||
}
|
||||
|
||||
|
||||
&.md-checked .md-icon:after {
|
||||
transform: rotate(45deg);
|
||||
position: absolute;
|
||||
left: 6px;
|
||||
top: 2px;
|
||||
display: table;
|
||||
width: 6px;
|
||||
height: 12px;
|
||||
border: 2px solid;
|
||||
border-top: 0;
|
||||
border-left: 0;
|
||||
content: ' ';
|
||||
}
|
||||
|
||||
.md-label {
|
||||
border: 1px dotted transparent;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
margin-left: 10px;
|
||||
vertical-align: middle;
|
||||
white-space: normal;
|
||||
pointer-events: none;
|
||||
user-select: text;
|
||||
}
|
||||
}
|
||||
172
UI/WebServerResources/scss/vendors/angular-material/components/checkbox/checkbox.spec.js
vendored
Normal file
172
UI/WebServerResources/scss/vendors/angular-material/components/checkbox/checkbox.spec.js
vendored
Normal file
@@ -0,0 +1,172 @@
|
||||
|
||||
describe('mdCheckbox', function() {
|
||||
var CHECKED_CSS = 'md-checked';
|
||||
|
||||
beforeEach(module('material.components.checkbox'));
|
||||
beforeEach(module('ngAria'));
|
||||
beforeEach(TestUtil.mockRaf);
|
||||
|
||||
it('should warn developers they need a label', inject(function($compile, $rootScope, $log){
|
||||
spyOn($log, "warn");
|
||||
|
||||
var element = $compile('<div>' +
|
||||
'<md-checkbox ng-model="blue">' +
|
||||
'</md-checkbox>' +
|
||||
'</div>')($rootScope);
|
||||
|
||||
expect($log.warn).toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
it('should copy text content to aria-label', inject(function($compile, $rootScope){
|
||||
var element = $compile('<div>' +
|
||||
'<md-checkbox ng-model="blue">' +
|
||||
'Some text' +
|
||||
'</md-checkbox>' +
|
||||
'</div>')($rootScope);
|
||||
|
||||
var cbElements = element.find('md-checkbox');
|
||||
expect(cbElements.eq(0).attr('aria-label')).toBe('Some text');
|
||||
}));
|
||||
|
||||
it('should set checked css class and aria-checked attributes', inject(function($compile, $rootScope) {
|
||||
var element = $compile('<div>' +
|
||||
'<md-checkbox ng-model="blue">' +
|
||||
'</md-checkbox>' +
|
||||
'<md-checkbox ng-model="green">' +
|
||||
'</md-checkbox>' +
|
||||
'</div>')($rootScope);
|
||||
|
||||
$rootScope.$apply(function(){
|
||||
$rootScope.blue = false;
|
||||
$rootScope.green = true;
|
||||
});
|
||||
|
||||
var cbElements = element.find('md-checkbox');
|
||||
|
||||
expect(cbElements.eq(0).hasClass(CHECKED_CSS)).toEqual(false);
|
||||
expect(cbElements.eq(1).hasClass(CHECKED_CSS)).toEqual(true);
|
||||
expect(cbElements.eq(0).attr('aria-checked')).toEqual('false');
|
||||
expect(cbElements.eq(1).attr('aria-checked')).toEqual('true');
|
||||
expect(cbElements.eq(0).attr('role')).toEqual('checkbox');
|
||||
}));
|
||||
|
||||
it('should be disabled with disabled attr', inject(function($compile, $rootScope) {
|
||||
var element = $compile('<div>' +
|
||||
'<md-checkbox ng-disabled="isDisabled" ng-model="blue">' +
|
||||
'</md-checkbox>' +
|
||||
'</div>')($rootScope);
|
||||
|
||||
var checkbox = element.find('md-checkbox');
|
||||
$rootScope.$apply('isDisabled = true');
|
||||
|
||||
$rootScope.$apply('blue = false');
|
||||
|
||||
checkbox.triggerHandler('click');
|
||||
expect($rootScope.blue).toBe(false);
|
||||
|
||||
$rootScope.$apply('isDisabled = false');
|
||||
|
||||
checkbox.triggerHandler('click');
|
||||
expect($rootScope.blue).toBe(true);
|
||||
|
||||
|
||||
}));
|
||||
|
||||
describe('ng core checkbox tests', function() {
|
||||
|
||||
var inputElm;
|
||||
var scope;
|
||||
var $compile;
|
||||
|
||||
beforeEach(inject(function(_$compile_, _$rootScope_) {
|
||||
scope = _$rootScope_;
|
||||
$compile = _$compile_;
|
||||
}));
|
||||
|
||||
function compileInput(html) {
|
||||
inputElm = $compile(html)(scope);
|
||||
}
|
||||
|
||||
function isChecked(cbEl) {
|
||||
return cbEl.hasClass(CHECKED_CSS);
|
||||
}
|
||||
|
||||
it('should format booleans', function() {
|
||||
compileInput('<md-checkbox ng-model="name" />');
|
||||
|
||||
scope.$apply("name = false");
|
||||
expect(isChecked(inputElm)).toBe(false);
|
||||
|
||||
scope.$apply("name = true");
|
||||
expect(isChecked(inputElm)).toBe(true);
|
||||
});
|
||||
|
||||
|
||||
it('should support type="checkbox" with non-standard capitalization', function() {
|
||||
compileInput('<md-checkbox ng-model="checkbox" />');
|
||||
|
||||
inputElm.triggerHandler('click');
|
||||
expect(scope.checkbox).toBe(true);
|
||||
|
||||
inputElm.triggerHandler('click');
|
||||
expect(scope.checkbox).toBe(false);
|
||||
});
|
||||
|
||||
|
||||
it('should allow custom enumeration', function() {
|
||||
compileInput('<md-checkbox ng-model="name" ng-true-value="\'y\'" ' +
|
||||
'ng-false-value="\'n\'">');
|
||||
|
||||
scope.$apply("name = 'y'");
|
||||
expect(isChecked(inputElm)).toBe(true);
|
||||
|
||||
scope.$apply("name = 'n'");
|
||||
expect(isChecked(inputElm)).toBe(false);
|
||||
|
||||
scope.$apply("name = 'something else'");
|
||||
expect(isChecked(inputElm)).toBe(false);
|
||||
|
||||
inputElm.triggerHandler('click');
|
||||
expect(scope.name).toEqual('y');
|
||||
|
||||
inputElm.triggerHandler('click');
|
||||
expect(scope.name).toEqual('n');
|
||||
});
|
||||
|
||||
|
||||
it('should throw if ngTrueValue is present and not a constant expression', function() {
|
||||
expect(function() {
|
||||
compileInput('<md-checkbox ng-model="value" ng-true-value="yes" />');
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
|
||||
it('should throw if ngFalseValue is present and not a constant expression', function() {
|
||||
expect(function() {
|
||||
compileInput('<md-checkbox ng-model="value" ng-false-value="no" />');
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
|
||||
it('should not throw if ngTrueValue or ngFalseValue are not present', function() {
|
||||
expect(function() {
|
||||
compileInput('<md-checkbox ng-model="value" />');
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
|
||||
it('should be required if false', function() {
|
||||
compileInput('<md-checkbox ng:model="value" required />');
|
||||
|
||||
inputElm.triggerHandler('click');
|
||||
expect(isChecked(inputElm)).toBe(true);
|
||||
expect(inputElm.hasClass('ng-valid')).toBe(true);
|
||||
|
||||
inputElm.triggerHandler('click');
|
||||
expect(isChecked(inputElm)).toBe(false);
|
||||
expect(inputElm.hasClass('ng-invalid')).toBe(true);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
<div ng-controller="AppCtrl">
|
||||
|
||||
<md-checkbox ng-model="data.cb1" aria-label="Checkbox 1">
|
||||
Checkbox 1: {{ data.cb1 }}
|
||||
</md-checkbox>
|
||||
|
||||
<md-checkbox ng-model="data.cb2" aria-label="Checkbox 2" ng-true-value="'yup'" ng-false-value="'nope'" class="md-warn">
|
||||
Checkbox 2 (md-warn): {{ data.cb2 }}
|
||||
</md-checkbox>
|
||||
|
||||
<md-checkbox ng-disabled="true" aria-label="Disabled checkbox" ng-model="data.cb3">
|
||||
Checkbox: Disabled
|
||||
</md-checkbox>
|
||||
|
||||
<md-checkbox ng-disabled="true" aria-label="Disabled checked checkbox" ng-model="data.cb4" ng-init="data.cb4=true">
|
||||
Checkbox: Disabled, Checked
|
||||
</md-checkbox>
|
||||
|
||||
<md-checkbox md-no-ink aria-label="Checkbox No Ink" ng-model="data.cb5" class="md-primary">
|
||||
Checkbox (md-primary): No Ink
|
||||
</md-checkbox>
|
||||
</div>
|
||||
13
UI/WebServerResources/scss/vendors/angular-material/components/checkbox/demoBasicUsage/script.js
vendored
Normal file
13
UI/WebServerResources/scss/vendors/angular-material/components/checkbox/demoBasicUsage/script.js
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
angular.module('checkboxDemo1', ['ngMaterial'])
|
||||
|
||||
.controller('AppCtrl', function($scope) {
|
||||
|
||||
$scope.data = {};
|
||||
$scope.data.cb1 = true;
|
||||
$scope.data.cb2 = false;
|
||||
$scope.data.cb3 = false;
|
||||
$scope.data.cb4 = false;
|
||||
$scope.data.cb5 = false;
|
||||
|
||||
});
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
body {
|
||||
padding: 20px;
|
||||
}
|
||||
5
UI/WebServerResources/scss/vendors/angular-material/components/content/content-theme.scss
vendored
Normal file
5
UI/WebServerResources/scss/vendors/angular-material/components/content/content-theme.scss
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
$content-background-color: $background-color-base !default;
|
||||
|
||||
md-content.md-THEME_NAME-theme {
|
||||
background-color: '{{background-hue-3}}';
|
||||
}
|
||||
53
UI/WebServerResources/scss/vendors/angular-material/components/content/content.js
vendored
Normal file
53
UI/WebServerResources/scss/vendors/angular-material/components/content/content.js
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc module
|
||||
* @name material.components.content
|
||||
*
|
||||
* @description
|
||||
* Scrollable content
|
||||
*/
|
||||
angular.module('material.components.content', [
|
||||
'material.core'
|
||||
])
|
||||
.directive('mdContent', mdContentDirective);
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name mdContent
|
||||
* @module material.components.content
|
||||
*
|
||||
* @restrict E
|
||||
*
|
||||
* @description
|
||||
* The `<md-content>` directive is a container element useful for scrollable content
|
||||
*
|
||||
* ### Restrictions
|
||||
*
|
||||
* - Add the `md-padding` class to make the content padded.
|
||||
*
|
||||
* @usage
|
||||
* <hljs lang="html">
|
||||
* <md-content class="md-padding">
|
||||
* Lorem ipsum dolor sit amet, ne quod novum mei.
|
||||
* </md-content>
|
||||
* </hljs>
|
||||
*
|
||||
*/
|
||||
function mdContentDirective($mdTheming) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
controller: ['$scope', '$element', ContentController],
|
||||
link: function($scope, $element, $attr) {
|
||||
$mdTheming($element);
|
||||
$scope.$broadcast('$mdContentLoaded', $element);
|
||||
}
|
||||
};
|
||||
|
||||
function ContentController($scope, $element) {
|
||||
this.$scope = $scope;
|
||||
this.$element = $element;
|
||||
}
|
||||
}
|
||||
})();
|
||||
28
UI/WebServerResources/scss/vendors/angular-material/components/content/content.scss
vendored
Normal file
28
UI/WebServerResources/scss/vendors/angular-material/components/content/content.scss
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
md-content {
|
||||
|
||||
display: block;
|
||||
position: relative;
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
|
||||
&[md-scroll-y] {
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
&[md-scroll-x] {
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
&[md-scroll-xy] {
|
||||
}
|
||||
|
||||
&.md-padding {
|
||||
padding: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: $layout-breakpoint-sm) {
|
||||
md-content.md-padding {
|
||||
padding: 16px;
|
||||
}
|
||||
}
|
||||
0
UI/WebServerResources/scss/vendors/angular-material/components/content/content.spec.js
vendored
Normal file
0
UI/WebServerResources/scss/vendors/angular-material/components/content/content.spec.js
vendored
Normal file
54
UI/WebServerResources/scss/vendors/angular-material/components/content/demoBasicUsage/index.html
vendored
Normal file
54
UI/WebServerResources/scss/vendors/angular-material/components/content/demoBasicUsage/index.html
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
|
||||
<div ng-controller="AppCtrl" layout="column" style="padding-bottom: 15px;">
|
||||
<md-toolbar class="md-accent">
|
||||
<div class="md-toolbar-tools">
|
||||
<span class="md-flex">Toolbar: md-accent</span>
|
||||
</div>
|
||||
</md-toolbar>
|
||||
|
||||
<md-content class="md-padding" style="height: 600px;">
|
||||
Lorem ipsum dolor sit amet, ne quod novum mei. Sea omnium invenire mediocrem at, in lobortis conclusionemque nam. Ne deleniti appetere reprimique pro, inani labitur disputationi te sed. At vix sale omnesque, id pro labitur reformidans accommodare, cum labores honestatis eu. Nec quem lucilius in, eam praesent reformidans no. Sed laudem aliquam ne.
|
||||
|
||||
<p>
|
||||
Facete delenit argumentum cum at. Pro rebum nostrum contentiones ad. Mel exerci tritani maiorum at, mea te audire phaedrum, mel et nibh aliquam. Malis causae equidem vel eu. Noster melius vis ea, duis alterum oporteat ea sea. Per cu vide munere fierent.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Ad sea dolor accusata consequuntur. Sit facete convenire reprehendunt et. Usu cu nonumy dissentiet, mei choro omnes fuisset ad. Te qui docendi accusam efficiantur, doming noster prodesset eam ei. In vel posse movet, ut convenire referrentur eum, ceteros singulis intellegam eu sit.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Sit saepe quaestio reprimique id, duo no congue nominati, cum id nobis facilisi. No est laoreet dissentias, idque consectetuer eam id. Clita possim assueverit cu his, solum virtute recteque et cum. Vel cu luptatum signiferumque, mel eu brute nostro senserit. Blandit euripidis consequat ex mei, atqui torquatos id cum, meliore luptatum ut usu. Cu zril perpetua gubergren pri. Accusamus rationibus instructior ei pro, eu nullam principes qui, reque justo omnes et quo.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Sint unum eam id. At sit fastidii theophrastus, mutat senserit repudiare et has. Atqui appareat repudiare ad nam, et ius alii incorrupte. Alii nullam libris his ei, meis aeterno at eum. Ne aeque tincidunt duo. In audire malorum mel, tamquam efficiantur has te.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Qui utamur tacimates quaestio ad, quod graece omnium ius ut. Pri ut vero debitis interpretaris, qui cu mentitum adipiscing disputationi. Voluptatum mediocritatem quo ut. Fabulas dolorem ei has, quem molestie persequeris et sit.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Est in vivendum comprehensam conclusionemque, alia cetero iriure no usu, te cibo deterruisset pro. Ludus epicurei quo id, ex cum iudicabit intellegebat. Ex modo deseruisse quo, mel noster menandri sententiae ea, duo et tritani malorum recteque. Nullam suscipit partiendo nec id, indoctum vulputate per ex. Et has enim habemus tibique. Cu latine electram cum, ridens propriae intellegat eu mea.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Duo at aliquid mnesarchum, nec ne impetus hendrerit. Ius id aeterno debitis atomorum, et sed feugait voluptua, brute tibique no vix. Eos modo esse ex, ei omittam imperdiet pro. Vel assum albucius incorrupte no. Vim viris prompta repudiare ne, vel ut viderer scripserit, dicant appetere argumentum mel ea. Eripuit feugait tincidunt pri ne, cu facilisi molestiae usu.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Qui utamur tacimates quaestio ad, quod graece omnium ius ut. Pri ut vero debitis interpretaris, qui cu mentitum adipiscing disputationi. Voluptatum mediocritatem quo ut. Fabulas dolorem ei has, quem molestie persequeris et sit.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Est in vivendum comprehensam conclusionemque, alia cetero iriure no usu, te cibo deterruisset pro. Ludus epicurei quo id, ex cum iudicabit intellegebat. Ex modo deseruisse quo, mel noster menandri sententiae ea, duo et tritani malorum recteque. Nullam suscipit partiendo nec id, indoctum vulputate per ex. Et has enim habemus tibique. Cu latine electram cum, ridens propriae intellegat eu mea.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Duo at aliquid mnesarchum, nec ne impetus hendrerit. Ius id aeterno debitis atomorum, et sed feugait voluptua, brute tibique no vix. Eos modo esse ex, ei omittam imperdiet pro. Vel assum albucius incorrupte no. Vim viris prompta repudiare ne, vel ut viderer scripserit, dicant appetere argumentum mel ea. Eripuit feugait tincidunt pri ne, cu facilisi molestiae usu.
|
||||
</p>
|
||||
|
||||
</md-content>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
angular.module('contentDemo1', ['ngMaterial'])
|
||||
|
||||
.controller('AppCtrl', function($scope) {
|
||||
|
||||
})
|
||||
@@ -0,0 +1,32 @@
|
||||
<md-dialog aria-label="Mango (Fruit)">
|
||||
|
||||
<md-content>
|
||||
<md-subheader class="md-sticky-no-effect">Mango (Fruit)</md-subheader>
|
||||
<p>
|
||||
The mango is a juicy stone fruit belonging to the genus Mangifera, consisting of numerous tropical fruiting trees, cultivated mostly for edible fruit. The majority of these species are found in nature as wild mangoes. They all belong to the flowering plant family Anacardiaceae. The mango is native to South and Southeast Asia, from where it has been distributed worldwide to become one of the most cultivated fruits in the tropics.
|
||||
</p>
|
||||
|
||||
<img style="margin: auto; max-width: 100%;" src="img/mangues.jpg">
|
||||
|
||||
<p>
|
||||
The highest concentration of Mangifera genus is in the western part of Malesia (Sumatra, Java and Borneo) and in Burma and India. While other Mangifera species (e.g. horse mango, M. foetida) are also grown on a more localized basis, Mangifera indica—the "common mango" or "Indian mango"—is the only mango tree commonly cultivated in many tropical and subtropical regions.
|
||||
</p>
|
||||
<p>
|
||||
It originated in Indian subcontinent (present day India and Pakistan) and Burma. It is the national fruit of India, Pakistan, and the Philippines, and the national tree of Bangladesh. In several cultures, its fruit and leaves are ritually used as floral decorations at weddings, public celebrations, and religious ceremonies.
|
||||
</p>
|
||||
</md-content>
|
||||
|
||||
<div class="md-actions" layout="row">
|
||||
<md-button href="http://en.wikipedia.org/wiki/Mango" target="_blank" hide show-md>
|
||||
More on Wikipedia
|
||||
</md-button>
|
||||
<span flex></span>
|
||||
<md-button ng-click="answer('not useful')">
|
||||
Not Useful
|
||||
</md-button>
|
||||
<md-button ng-click="answer('useful')" class="md-primary">
|
||||
Useful
|
||||
</md-button>
|
||||
</div>
|
||||
|
||||
</md-dialog>
|
||||
24
UI/WebServerResources/scss/vendors/angular-material/components/dialog/demoBasicUsage/index.html
vendored
Normal file
24
UI/WebServerResources/scss/vendors/angular-material/components/dialog/demoBasicUsage/index.html
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<div ng-controller="AppCtrl" class="full" layout="column" layout-margin>
|
||||
<p class="inset">
|
||||
Open a dialog over the app's content. Press escape or click outside to close the dialog.
|
||||
</p>
|
||||
|
||||
<div layout="column" layout-align="center" >
|
||||
<md-button class="md-primary" ng-click="showAlert($event)">
|
||||
Alert Dialog
|
||||
</md-button>
|
||||
<div class="gap"></div>
|
||||
<md-button class="md-primary" ng-click="showConfirm($event)">
|
||||
Confirm Dialog
|
||||
</md-button>
|
||||
<div class="gap"></div>
|
||||
<md-button class="md-primary" ng-click="showAdvanced($event)">
|
||||
Custom Dialog
|
||||
</md-button>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
<b layout="row" layout-align="center center" layout-margin>
|
||||
{{alert}}
|
||||
</b>
|
||||
</div>
|
||||
59
UI/WebServerResources/scss/vendors/angular-material/components/dialog/demoBasicUsage/script.js
vendored
Normal file
59
UI/WebServerResources/scss/vendors/angular-material/components/dialog/demoBasicUsage/script.js
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
angular.module('dialogDemo1', ['ngMaterial'])
|
||||
|
||||
.controller('AppCtrl', function($scope, $mdDialog) {
|
||||
$scope.alert = '';
|
||||
|
||||
$scope.showAlert = function(ev) {
|
||||
$mdDialog.show(
|
||||
$mdDialog.alert()
|
||||
.title('This is an alert title')
|
||||
.content('You can specify some description text in here.')
|
||||
.ariaLabel('Password notification')
|
||||
.ok('Got it!')
|
||||
.targetEvent(ev)
|
||||
);
|
||||
};
|
||||
|
||||
$scope.showConfirm = function(ev) {
|
||||
var confirm = $mdDialog.confirm()
|
||||
.title('Would you like to delete your debt?')
|
||||
.content('All of the banks have agreed to forgive you your debts.')
|
||||
.ariaLabel('Lucky day')
|
||||
.ok('Please do it!')
|
||||
.cancel('Sounds like a scam')
|
||||
.targetEvent(ev);
|
||||
|
||||
$mdDialog.show(confirm).then(function() {
|
||||
$scope.alert = 'You decided to get rid of your debt.';
|
||||
}, function() {
|
||||
$scope.alert = 'You decided to keep your debt.';
|
||||
});
|
||||
};
|
||||
|
||||
$scope.showAdvanced = function(ev) {
|
||||
$mdDialog.show({
|
||||
controller: DialogController,
|
||||
templateUrl: 'dialog1.tmpl.html',
|
||||
targetEvent: ev,
|
||||
})
|
||||
.then(function(answer) {
|
||||
$scope.alert = 'You said the information was "' + answer + '".';
|
||||
}, function() {
|
||||
$scope.alert = 'You cancelled the dialog.';
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
function DialogController($scope, $mdDialog) {
|
||||
$scope.hide = function() {
|
||||
$mdDialog.hide();
|
||||
};
|
||||
|
||||
$scope.cancel = function() {
|
||||
$mdDialog.cancel();
|
||||
};
|
||||
|
||||
$scope.answer = function(answer) {
|
||||
$mdDialog.hide(answer);
|
||||
};
|
||||
}
|
||||
34
UI/WebServerResources/scss/vendors/angular-material/components/dialog/demoBasicUsage/style.css
vendored
Normal file
34
UI/WebServerResources/scss/vendors/angular-material/components/dialog/demoBasicUsage/style.css
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
.full {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.gap {
|
||||
width:50px;
|
||||
}
|
||||
|
||||
|
||||
.md-subheader {
|
||||
background-color: #dcedc8;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
h2.md-subheader {
|
||||
margin: 0px;
|
||||
margin-left: -24px;
|
||||
margin-right: -24px;
|
||||
margin-top: -24px;
|
||||
}
|
||||
|
||||
h2.md-subheader.md-sticky-clone {
|
||||
margin-right:0px;
|
||||
margin-top:0px;
|
||||
|
||||
box-shadow: 0px 2px 4px 0 rgba(0,0,0,0.16);
|
||||
}
|
||||
|
||||
h2 .md-subheader-content {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
|
||||
11
UI/WebServerResources/scss/vendors/angular-material/components/dialog/dialog-theme.scss
vendored
Normal file
11
UI/WebServerResources/scss/vendors/angular-material/components/dialog/dialog-theme.scss
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
$dialog-border-radius: 4px !default;
|
||||
|
||||
md-dialog.md-THEME_NAME-theme {
|
||||
border-radius: $dialog-border-radius;
|
||||
background-color: '{{background-hue-3}}';
|
||||
|
||||
&.md-content-overflow .md-actions {
|
||||
border-top-color: '{{foreground-4}}';
|
||||
}
|
||||
}
|
||||
|
||||
485
UI/WebServerResources/scss/vendors/angular-material/components/dialog/dialog.js
vendored
Normal file
485
UI/WebServerResources/scss/vendors/angular-material/components/dialog/dialog.js
vendored
Normal file
@@ -0,0 +1,485 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc module
|
||||
* @name material.components.dialog
|
||||
*/
|
||||
angular.module('material.components.dialog', [
|
||||
'material.core',
|
||||
'material.components.backdrop'
|
||||
])
|
||||
.directive('mdDialog', MdDialogDirective)
|
||||
.provider('$mdDialog', MdDialogProvider);
|
||||
|
||||
function MdDialogDirective($$rAF, $mdTheming) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
link: function(scope, element, attr) {
|
||||
$mdTheming(element);
|
||||
$$rAF(function() {
|
||||
var content = element[0].querySelector('md-content');
|
||||
if (content && content.scrollHeight > content.clientHeight) {
|
||||
element.addClass('md-content-overflow');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name $mdDialog
|
||||
* @module material.components.dialog
|
||||
*
|
||||
* @description
|
||||
* `$mdDialog` opens a dialog over the app and provides a simple promise API.
|
||||
*
|
||||
* ### Restrictions
|
||||
*
|
||||
* - The dialog is always given an isolate scope.
|
||||
* - The dialog's template must have an outer `<md-dialog>` element.
|
||||
* Inside, use an `<md-content>` element for the dialog's content, and use
|
||||
* an element with class `md-actions` for the dialog's actions.
|
||||
*
|
||||
* @usage
|
||||
* ##### HTML
|
||||
*
|
||||
* <hljs lang="html">
|
||||
* <div ng-app="demoApp" ng-controller="EmployeeController">
|
||||
* <md-button ng-click="showAlert()" class="md-raised md-warn">
|
||||
* Employee Alert!
|
||||
* </md-button>
|
||||
* <md-button ng-click="closeAlert()" ng-disabled="!hasAlert()" class="md-raised">
|
||||
* Close Alert
|
||||
* </md-button>
|
||||
* <md-button ng-click="showGreeting($event)" class="md-raised md-primary" >
|
||||
* Greet Employee
|
||||
* </md-button>
|
||||
* </div>
|
||||
* </hljs>
|
||||
*
|
||||
* ##### JavaScript
|
||||
*
|
||||
* <hljs lang="js">
|
||||
* (function(angular, undefined){
|
||||
* "use strict";
|
||||
*
|
||||
* angular
|
||||
* .module('demoApp', ['ngMaterial'])
|
||||
* .controller('EmployeeController', EmployeeEditor)
|
||||
* .controller('GreetingController', GreetingController);
|
||||
*
|
||||
* // Fictitious Employee Editor to show how to use simple and complex dialogs.
|
||||
*
|
||||
* function EmployeeEditor($scope, $mdDialog) {
|
||||
* var alert;
|
||||
*
|
||||
* $scope.showAlert = showAlert;
|
||||
* $scope.closeAlert = closeAlert;
|
||||
* $scope.showGreeting = showCustomGreeting;
|
||||
*
|
||||
* $scope.hasAlert = function() { return !!alert };
|
||||
* $scope.userName = $scope.userName || 'Bobby';
|
||||
*
|
||||
* // Dialog #1 - Show simple alert dialog and cache
|
||||
* // reference to dialog instance
|
||||
*
|
||||
* function showAlert() {
|
||||
* alert = $mdDialog.alert()
|
||||
* .title('Attention, ' + $scope.userName)
|
||||
* .content('This is an example of how easy dialogs can be!')
|
||||
* .ok('Close');
|
||||
*
|
||||
* $mdDialog
|
||||
* .show( alert )
|
||||
* .finally(function() {
|
||||
* alert = undefined;
|
||||
* });
|
||||
* }
|
||||
*
|
||||
* // Close the specified dialog instance and resolve with 'finished' flag
|
||||
* // Normally this is not needed, just use '$mdDialog.hide()' to close
|
||||
* // the most recent dialog popup.
|
||||
*
|
||||
* function closeAlert() {
|
||||
* $mdDialog.hide( alert, "finished" );
|
||||
* alert = undefined;
|
||||
* }
|
||||
*
|
||||
* // Dialog #2 - Demonstrate more complex dialogs construction and popup.
|
||||
*
|
||||
* function showCustomGreeting($event) {
|
||||
* $mdDialog.show({
|
||||
* targetEvent: $event,
|
||||
* template:
|
||||
* '<md-dialog>' +
|
||||
*
|
||||
* ' <md-content>Hello {{ employee }}!</md-content>' +
|
||||
*
|
||||
* ' <div class="md-actions">' +
|
||||
* ' <md-button ng-click="closeDialog()">' +
|
||||
* ' Close Greeting' +
|
||||
*
|
||||
* ' </md-button>' +
|
||||
* ' </div>' +
|
||||
* '</md-dialog>',
|
||||
* controller: 'GreetingController',
|
||||
* onComplete: afterShowAnimation,
|
||||
* locals: { employee: $scope.userName }
|
||||
* });
|
||||
*
|
||||
* // When the 'enter' animation finishes...
|
||||
*
|
||||
* function afterShowAnimation(scope, element, options) {
|
||||
* // post-show code here: DOM element focus, etc.
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* // Greeting controller used with the more complex 'showCustomGreeting()' custom dialog
|
||||
*
|
||||
* function GreetingController($scope, $mdDialog, employee) {
|
||||
* // Assigned from construction <code>locals</code> options...
|
||||
* $scope.employee = employee;
|
||||
*
|
||||
* $scope.closeDialog = function() {
|
||||
* // Easily hides most recent dialog shown...
|
||||
* // no specific instance reference is needed.
|
||||
* $mdDialog.hide();
|
||||
* };
|
||||
* }
|
||||
*
|
||||
* })(angular);
|
||||
* </hljs>
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name $mdDialog#alert
|
||||
*
|
||||
* @description
|
||||
* Builds a preconfigured dialog with the specified message.
|
||||
*
|
||||
* @returns {obj} an `$mdDialogPreset` with the chainable configuration methods:
|
||||
*
|
||||
* - $mdDialogPreset#title(string) - sets title to string
|
||||
* - $mdDialogPreset#content(string) - sets content / message to string
|
||||
* - $mdDialogPreset#ok(string) - sets okay button text to string
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name $mdDialog#confirm
|
||||
*
|
||||
* @description
|
||||
* Builds a preconfigured dialog with the specified message. You can call show and the promise returned
|
||||
* will be resolved only if the user clicks the confirm action on the dialog.
|
||||
*
|
||||
* @returns {obj} an `$mdDialogPreset` with the chainable configuration methods:
|
||||
*
|
||||
* Additionally, it supports the following methods:
|
||||
*
|
||||
* - $mdDialogPreset#title(string) - sets title to string
|
||||
* - $mdDialogPreset#content(string) - sets content / message to string
|
||||
* - $mdDialogPreset#ok(string) - sets okay button text to string
|
||||
* - $mdDialogPreset#cancel(string) - sets cancel button text to string
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name $mdDialog#show
|
||||
*
|
||||
* @description
|
||||
* Show a dialog with the specified options.
|
||||
*
|
||||
* @param {object} optionsOrPreset Either provide an `$mdDialogPreset` returned from `alert()`,
|
||||
* `confirm()` or an options object with the following properties:
|
||||
* - `templateUrl` - `{string=}`: The url of a template that will be used as the content
|
||||
* of the dialog.
|
||||
* - `template` - `{string=}`: Same as templateUrl, except this is an actual template string.
|
||||
* - `targetEvent` - `{DOMClickEvent=}`: A click's event object. When passed in as an option,
|
||||
* the location of the click will be used as the starting point for the opening animation
|
||||
* of the the dialog.
|
||||
* - `disableParentScroll` - `{boolean=}`: Whether to disable scrolling while the dialog is open.
|
||||
* Default true.
|
||||
* - `hasBackdrop` - `{boolean=}`: Whether there should be an opaque backdrop behind the dialog.
|
||||
* Default true.
|
||||
* - `clickOutsideToClose` - `{boolean=}`: Whether the user can click outside the dialog to
|
||||
* close it. Default true.
|
||||
* - `escapeToClose` - `{boolean=}`: Whether the user can press escape to close the dialog.
|
||||
* Default true.
|
||||
* - `controller` - `{string=}`: The controller to associate with the dialog. The controller
|
||||
* will be injected with the local `$hideDialog`, which is a function used to hide the dialog.
|
||||
* - `locals` - `{object=}`: An object containing key/value pairs. The keys will be used as names
|
||||
* of values to inject into the controller. For example, `locals: {three: 3}` would inject
|
||||
* `three` into the controller, with the value 3. If `bindToController` is true, they will be
|
||||
* copied to the controller instead.
|
||||
* - `bindToController` - `bool`: bind the locals to the controller, instead of passing them in
|
||||
* - `resolve` - `{object=}`: Similar to locals, except it takes promises as values, and the
|
||||
* dialog will not open until all of the promises resolve.
|
||||
* - `controllerAs` - `{string=}`: An alias to assign the controller to on the scope.
|
||||
* - `parent` - `{element=}`: The element to append the dialog to. Defaults to appending
|
||||
* to the root element of the application.
|
||||
* - `onComplete` `{function=}`: Callback function used to announce when the show() action is
|
||||
* finished.
|
||||
*
|
||||
* @returns {promise} A promise that can be resolved with `$mdDialog.hide()` or
|
||||
* rejected with `mdDialog.cancel()`.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name $mdDialog#hide
|
||||
*
|
||||
* @description
|
||||
* Hide an existing dialog and resolve the promise returned from `$mdDialog.show()`.
|
||||
*
|
||||
* @param {*=} response An argument for the resolved promise.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name $mdDialog#cancel
|
||||
*
|
||||
* @description
|
||||
* Hide an existing dialog and reject the promise returned from `$mdDialog.show()`.
|
||||
*
|
||||
* @param {*=} response An argument for the rejected promise.
|
||||
*/
|
||||
|
||||
function MdDialogProvider($$interimElementProvider) {
|
||||
|
||||
var alertDialogMethods = ['title', 'content', 'ariaLabel', 'ok'];
|
||||
|
||||
return $$interimElementProvider('$mdDialog')
|
||||
.setDefaults({
|
||||
methods: ['disableParentScroll', 'hasBackdrop', 'clickOutsideToClose', 'escapeToClose', 'targetEvent'],
|
||||
options: dialogDefaultOptions
|
||||
})
|
||||
.addPreset('alert', {
|
||||
methods: ['title', 'content', 'ariaLabel', 'ok'],
|
||||
options: advancedDialogOptions
|
||||
})
|
||||
.addPreset('confirm', {
|
||||
methods: ['title', 'content', 'ariaLabel', 'ok', 'cancel'],
|
||||
options: advancedDialogOptions
|
||||
});
|
||||
|
||||
/* @ngInject */
|
||||
function advancedDialogOptions($mdDialog) {
|
||||
return {
|
||||
template: [
|
||||
'<md-dialog aria-label="{{ dialog.ariaLabel }}">',
|
||||
'<md-content>',
|
||||
'<h2>{{ dialog.title }}</h2>',
|
||||
'<p>{{ dialog.content }}</p>',
|
||||
'</md-content>',
|
||||
'<div class="md-actions">',
|
||||
'<md-button ng-if="dialog.$type == \'confirm\'" ng-click="dialog.abort()">',
|
||||
'{{ dialog.cancel }}',
|
||||
'</md-button>',
|
||||
'<md-button ng-click="dialog.hide()" class="md-primary">',
|
||||
'{{ dialog.ok }}',
|
||||
'</md-button>',
|
||||
'</div>',
|
||||
'</md-dialog>'
|
||||
].join(''),
|
||||
controller: function mdDialogCtrl() {
|
||||
this.hide = function() {
|
||||
$mdDialog.hide(true);
|
||||
};
|
||||
this.abort = function() {
|
||||
$mdDialog.cancel();
|
||||
};
|
||||
},
|
||||
controllerAs: 'dialog',
|
||||
bindToController: true
|
||||
};
|
||||
}
|
||||
|
||||
/* @ngInject */
|
||||
function dialogDefaultOptions($timeout, $rootElement, $compile, $animate, $mdAria, $document,
|
||||
$mdUtil, $mdConstant, $mdTheming, $$rAF, $q, $mdDialog) {
|
||||
return {
|
||||
hasBackdrop: true,
|
||||
isolateScope: true,
|
||||
onShow: onShow,
|
||||
onRemove: onRemove,
|
||||
clickOutsideToClose: true,
|
||||
escapeToClose: true,
|
||||
targetEvent: null,
|
||||
disableParentScroll: true,
|
||||
transformTemplate: function(template) {
|
||||
return '<div class="md-dialog-container">' + template + '</div>';
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// On show method for dialogs
|
||||
function onShow(scope, element, options) {
|
||||
// Incase the user provides a raw dom element, always wrap it in jqLite
|
||||
options.parent = angular.element(options.parent);
|
||||
|
||||
options.popInTarget = angular.element((options.targetEvent || {}).target);
|
||||
var closeButton = findCloseButton();
|
||||
|
||||
configureAria(element.find('md-dialog'));
|
||||
|
||||
if (options.hasBackdrop) {
|
||||
options.backdrop = angular.element('<md-backdrop class="md-dialog-backdrop md-opaque">');
|
||||
$mdTheming.inherit(options.backdrop, options.parent);
|
||||
$animate.enter(options.backdrop, options.parent);
|
||||
}
|
||||
|
||||
if (options.disableParentScroll) {
|
||||
options.oldOverflowStyle = options.parent.css('overflow');
|
||||
options.parent.css('overflow', 'hidden');
|
||||
}
|
||||
|
||||
return dialogPopIn(
|
||||
element,
|
||||
options.parent,
|
||||
options.popInTarget && options.popInTarget.length && options.popInTarget
|
||||
)
|
||||
.then(function() {
|
||||
if (options.escapeToClose) {
|
||||
options.rootElementKeyupCallback = function(e) {
|
||||
if (e.keyCode === $mdConstant.KEY_CODE.ESCAPE) {
|
||||
$timeout($mdDialog.cancel);
|
||||
}
|
||||
};
|
||||
$rootElement.on('keyup', options.rootElementKeyupCallback);
|
||||
}
|
||||
|
||||
if (options.clickOutsideToClose) {
|
||||
options.dialogClickOutsideCallback = function(e) {
|
||||
// Only close if we click the flex container outside the backdrop
|
||||
if (e.target === element[0]) {
|
||||
$timeout($mdDialog.cancel);
|
||||
}
|
||||
};
|
||||
element.on('click', options.dialogClickOutsideCallback);
|
||||
}
|
||||
closeButton.focus();
|
||||
});
|
||||
|
||||
|
||||
function findCloseButton() {
|
||||
//If no element with class dialog-close, try to find the last
|
||||
//button child in md-actions and assume it is a close button
|
||||
var closeButton = element[0].querySelector('.dialog-close');
|
||||
if (!closeButton) {
|
||||
var actionButtons = element[0].querySelectorAll('.md-actions button');
|
||||
closeButton = actionButtons[ actionButtons.length - 1 ];
|
||||
}
|
||||
return angular.element(closeButton);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// On remove function for all dialogs
|
||||
function onRemove(scope, element, options) {
|
||||
|
||||
if (options.backdrop) {
|
||||
$animate.leave(options.backdrop);
|
||||
}
|
||||
if (options.disableParentScroll) {
|
||||
options.parent.css('overflow', options.oldOverflowStyle);
|
||||
$document[0].removeEventListener('scroll', options.captureScroll, true);
|
||||
}
|
||||
if (options.escapeToClose) {
|
||||
$rootElement.off('keyup', options.rootElementKeyupCallback);
|
||||
}
|
||||
if (options.clickOutsideToClose) {
|
||||
element.off('click', options.dialogClickOutsideCallback);
|
||||
}
|
||||
return dialogPopOut(
|
||||
element,
|
||||
options.parent,
|
||||
options.popInTarget && options.popInTarget.length && options.popInTarget
|
||||
).then(function() {
|
||||
options.scope.$destroy();
|
||||
element.remove();
|
||||
options.popInTarget && options.popInTarget.focus();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject ARIA-specific attributes appropriate for Dialogs
|
||||
*/
|
||||
function configureAria(element) {
|
||||
element.attr({
|
||||
'role': 'dialog'
|
||||
});
|
||||
|
||||
var dialogContent = element.find('md-content');
|
||||
if (dialogContent.length === 0){
|
||||
dialogContent = element;
|
||||
}
|
||||
$mdAria.expectAsync(element, 'aria-label', function() {
|
||||
var words = dialogContent.text().split(/\s+/);
|
||||
if (words.length > 3) words = words.slice(0,3).concat('...');
|
||||
return words.join(' ');
|
||||
});
|
||||
}
|
||||
|
||||
function dialogPopIn(container, parentElement, clickElement) {
|
||||
var dialogEl = container.find('md-dialog');
|
||||
|
||||
parentElement.append(container);
|
||||
transformToClickElement(dialogEl, clickElement);
|
||||
|
||||
$$rAF(function() {
|
||||
dialogEl.addClass('transition-in')
|
||||
.css($mdConstant.CSS.TRANSFORM, '');
|
||||
});
|
||||
|
||||
return dialogTransitionEnd(dialogEl);
|
||||
}
|
||||
|
||||
function dialogPopOut(container, parentElement, clickElement) {
|
||||
var dialogEl = container.find('md-dialog');
|
||||
|
||||
dialogEl.addClass('transition-out').removeClass('transition-in');
|
||||
transformToClickElement(dialogEl, clickElement);
|
||||
|
||||
return dialogTransitionEnd(dialogEl);
|
||||
}
|
||||
|
||||
function transformToClickElement(dialogEl, clickElement) {
|
||||
if (clickElement) {
|
||||
var clickRect = clickElement[0].getBoundingClientRect();
|
||||
var dialogRect = dialogEl[0].getBoundingClientRect();
|
||||
|
||||
var scaleX = Math.min(0.5, clickRect.width / dialogRect.width);
|
||||
var scaleY = Math.min(0.5, clickRect.height / dialogRect.height);
|
||||
|
||||
dialogEl.css($mdConstant.CSS.TRANSFORM, 'translate3d(' +
|
||||
(-dialogRect.left + clickRect.left + clickRect.width/2 - dialogRect.width/2) + 'px,' +
|
||||
(-dialogRect.top + clickRect.top + clickRect.height/2 - dialogRect.height/2) + 'px,' +
|
||||
'0) scale(' + scaleX + ',' + scaleY + ')'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function dialogTransitionEnd(dialogEl) {
|
||||
var deferred = $q.defer();
|
||||
dialogEl.on($mdConstant.CSS.TRANSITIONEND, finished);
|
||||
function finished(ev) {
|
||||
//Make sure this transitionend didn't bubble up from a child
|
||||
if (ev.target === dialogEl[0]) {
|
||||
dialogEl.off($mdConstant.CSS.TRANSITIONEND, finished);
|
||||
deferred.resolve();
|
||||
}
|
||||
}
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
||||
65
UI/WebServerResources/scss/vendors/angular-material/components/dialog/dialog.scss
vendored
Normal file
65
UI/WebServerResources/scss/vendors/angular-material/components/dialog/dialog.scss
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
.md-dialog-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: $z-index-dialog;
|
||||
}
|
||||
|
||||
md-dialog {
|
||||
&.transition-in {
|
||||
opacity: 1;
|
||||
transition: $swift-ease-out;
|
||||
transform: translate3d(0,0,0) scale(1.0);
|
||||
}
|
||||
&.transition-out {
|
||||
transition: $swift-ease-out;
|
||||
transform: translate3d(0,100%,0) scale(0.2);
|
||||
}
|
||||
|
||||
opacity: 0;
|
||||
min-width: 240px;
|
||||
max-width: 80%;
|
||||
max-height: 80%;
|
||||
margin: auto;
|
||||
position: relative;
|
||||
overflow: hidden; // stop content from leaking out of dialog parent
|
||||
|
||||
box-shadow: $whiteframe-shadow-z5;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
md-content {
|
||||
order: 1;
|
||||
padding: 24px;
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
|
||||
*:first-child {
|
||||
margin-top: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.md-actions {
|
||||
display: flex;
|
||||
order: 2;
|
||||
box-sizing: border-box;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
padding: 16px 16px;
|
||||
min-height: $baseline-grid * 5;
|
||||
|
||||
> * {
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
&.md-content-overflow .md-actions {
|
||||
border-top: 1px solid;
|
||||
}
|
||||
|
||||
}
|
||||
479
UI/WebServerResources/scss/vendors/angular-material/components/dialog/dialog.spec.js
vendored
Normal file
479
UI/WebServerResources/scss/vendors/angular-material/components/dialog/dialog.spec.js
vendored
Normal file
@@ -0,0 +1,479 @@
|
||||
describe('$mdDialog', function() {
|
||||
|
||||
beforeEach(TestUtil.mockRaf);
|
||||
beforeEach(module('material.components.dialog', 'ngAnimateMock'));
|
||||
|
||||
beforeEach(inject(function spyOnMdEffects($$q, $animate) {
|
||||
spyOn($animate, 'leave').andCallFake(function(element) {
|
||||
element.remove();
|
||||
return $$q.when();
|
||||
});
|
||||
spyOn($animate, 'enter').andCallFake(function(element, parent) {
|
||||
parent.append(element);
|
||||
return $$q.when();
|
||||
});
|
||||
}));
|
||||
|
||||
describe('#alert()', function() {
|
||||
hasConfigurationMethods('alert', [
|
||||
'title', 'content', 'ariaLabel',
|
||||
'ok', 'targetEvent'
|
||||
]);
|
||||
|
||||
it('shows a basic alert dialog', inject(function($animate, $rootScope, $mdDialog, $mdConstant) {
|
||||
var parent = angular.element('<div>');
|
||||
var resolved = false;
|
||||
$mdDialog.show(
|
||||
$mdDialog.alert({
|
||||
parent: parent
|
||||
})
|
||||
.title('Title')
|
||||
.content('Hello world')
|
||||
.ok('Next')
|
||||
).then(function() {
|
||||
resolved = true;
|
||||
});
|
||||
|
||||
$rootScope.$apply();
|
||||
var container = angular.element(parent[0].querySelector('.md-dialog-container'));
|
||||
container.triggerHandler('transitionend');
|
||||
$rootScope.$apply();
|
||||
|
||||
var title = angular.element(parent[0].querySelector('h2'));
|
||||
expect(title.text()).toBe('Title');
|
||||
var content = parent.find('p');
|
||||
expect(content.text()).toBe('Hello world');
|
||||
var buttons = parent.find('md-button');
|
||||
expect(buttons.length).toBe(1);
|
||||
expect(buttons.eq(0).text()).toBe('Next');
|
||||
buttons.eq(0).triggerHandler('click');
|
||||
$rootScope.$apply();
|
||||
parent.find('md-dialog').triggerHandler('transitionend');
|
||||
$rootScope.$apply();
|
||||
expect(parent.find('h2').length).toBe(0);
|
||||
expect(resolved).toBe(true);
|
||||
}));
|
||||
});
|
||||
|
||||
describe('#confirm()', function() {
|
||||
hasConfigurationMethods('confirm', [
|
||||
'title', 'content', 'ariaLabel',
|
||||
'ok', 'cancel', 'targetEvent'
|
||||
]);
|
||||
|
||||
it('shows a basic confirm dialog', inject(function($rootScope, $mdDialog, $animate, $mdConstant) {
|
||||
var parent = angular.element('<div>');
|
||||
var rejected = false;
|
||||
$mdDialog.show(
|
||||
$mdDialog.confirm({
|
||||
parent: parent
|
||||
})
|
||||
.title('Title')
|
||||
.content('Hello world')
|
||||
.ok('Next')
|
||||
.cancel('Forget it')
|
||||
).catch(function() {
|
||||
rejected = true;
|
||||
});
|
||||
|
||||
$rootScope.$apply();
|
||||
var container = angular.element(parent[0].querySelector('.md-dialog-container'));
|
||||
container.triggerHandler('transitionend');
|
||||
$rootScope.$apply();
|
||||
|
||||
var title = parent.find('h2');
|
||||
expect(title.text()).toBe('Title');
|
||||
var content = parent.find('p');
|
||||
expect(content.text()).toBe('Hello world');
|
||||
var buttons = parent.find('md-button');
|
||||
expect(buttons.length).toBe(2);
|
||||
expect(buttons.eq(0).text()).toBe('Next');
|
||||
expect(buttons.eq(1).text()).toBe('Forget it');
|
||||
buttons.eq(1).triggerHandler('click');
|
||||
$rootScope.$digest();
|
||||
parent.find('md-dialog').triggerHandler('transitionend');
|
||||
$rootScope.$apply();
|
||||
expect(parent.find('h2').length).toBe(0);
|
||||
expect(rejected).toBe(true);
|
||||
}));
|
||||
});
|
||||
|
||||
describe('#build()', function() {
|
||||
it('should support onComplete callbacks within `show()`', inject(function($mdDialog, $rootScope, $timeout, $mdConstant) {
|
||||
|
||||
var template = '<md-dialog>Hello</md-dialog>';
|
||||
var parent = angular.element('<div>');
|
||||
var ready = false;
|
||||
|
||||
$mdDialog.show({
|
||||
template: template,
|
||||
parent: parent,
|
||||
onComplete: function(scope, element, options) {
|
||||
expect( arguments.length ).toEqual( 3 );
|
||||
ready = true;
|
||||
}
|
||||
});
|
||||
$rootScope.$apply();
|
||||
|
||||
expect(ready).toBe( false );
|
||||
|
||||
var container = angular.element(parent[0].querySelector('.md-dialog-container'));
|
||||
parent.find('md-dialog').triggerHandler('transitionend');
|
||||
$rootScope.$apply();
|
||||
|
||||
container = angular.element(parent[0].querySelector('.md-dialog-container'));
|
||||
expect(container.length).toBe(1);
|
||||
expect(ready).toBe( true );
|
||||
}));
|
||||
|
||||
it('should append dialog with container', inject(function($mdDialog, $rootScope) {
|
||||
|
||||
var template = '<md-dialog>Hello</md-dialog>';
|
||||
var parent = angular.element('<div>');
|
||||
|
||||
$mdDialog.show({
|
||||
template: template,
|
||||
parent: parent
|
||||
});
|
||||
|
||||
$rootScope.$apply();
|
||||
|
||||
var container = parent[0].querySelectorAll('.md-dialog-container');
|
||||
expect(container.length).toBe(1);
|
||||
}));
|
||||
|
||||
it('should escapeToClose == true', inject(function($mdDialog, $rootScope, $rootElement, $timeout, $animate, $mdConstant) {
|
||||
var parent = angular.element('<div>');
|
||||
$mdDialog.show({
|
||||
template: '<md-dialog>',
|
||||
parent: parent,
|
||||
escapeToClose: true
|
||||
});
|
||||
$rootScope.$apply();
|
||||
|
||||
var container = angular.element(parent[0].querySelector('.md-dialog-container'));
|
||||
parent.find('md-dialog').triggerHandler('transitionend');
|
||||
$rootScope.$apply();
|
||||
|
||||
expect(parent.find('md-dialog').length).toBe(1);
|
||||
|
||||
$rootElement.triggerHandler({type: 'keyup',
|
||||
keyCode: $mdConstant.KEY_CODE.ESCAPE
|
||||
});
|
||||
|
||||
$timeout.flush();
|
||||
parent.find('md-dialog').triggerHandler('transitionend');
|
||||
$rootScope.$apply();
|
||||
expect(parent.find('md-dialog').length).toBe(0);
|
||||
}));
|
||||
|
||||
it('should escapeToClose == false', inject(function($mdDialog, $rootScope, $rootElement, $timeout, $animate, $mdConstant) {
|
||||
var parent = angular.element('<div>');
|
||||
$mdDialog.show({
|
||||
template: '<md-dialog>',
|
||||
parent: parent,
|
||||
escapeToClose: false
|
||||
});
|
||||
$rootScope.$apply();
|
||||
|
||||
var container = angular.element(parent[0].querySelector('.md-dialog-container'));
|
||||
container.triggerHandler('transitionend');
|
||||
$rootScope.$apply();
|
||||
|
||||
expect(parent.find('md-dialog').length).toBe(1);
|
||||
|
||||
$rootElement.triggerHandler({ type: 'keyup', keyCode: $mdConstant.KEY_CODE.ESCAPE });
|
||||
|
||||
$timeout.flush();
|
||||
$animate.triggerCallbacks();
|
||||
expect(parent.find('md-dialog').length).toBe(1);
|
||||
}));
|
||||
|
||||
it('should clickOutsideToClose == true', inject(function($mdDialog, $rootScope, $timeout, $animate, $mdConstant) {
|
||||
|
||||
var parent = angular.element('<div>');
|
||||
$mdDialog.show({
|
||||
template: '<md-dialog>',
|
||||
parent: parent,
|
||||
clickOutsideToClose: true
|
||||
});
|
||||
$rootScope.$apply();
|
||||
|
||||
var container = angular.element(parent[0].querySelector('.md-dialog-container'));
|
||||
parent.find('md-dialog').triggerHandler('transitionend');
|
||||
$rootScope.$apply();
|
||||
|
||||
expect(parent.find('md-dialog').length).toBe(1);
|
||||
|
||||
container.triggerHandler({
|
||||
type: 'click',
|
||||
target: container[0]
|
||||
});
|
||||
$timeout.flush();
|
||||
parent.find('md-dialog').triggerHandler('transitionend');
|
||||
$rootScope.$apply();
|
||||
|
||||
expect(parent.find('md-dialog').length).toBe(0);
|
||||
}));
|
||||
|
||||
it('should clickOutsideToClose == false', inject(function($mdDialog, $rootScope, $timeout, $animate) {
|
||||
|
||||
var parent = angular.element('<div>');
|
||||
$mdDialog.show({
|
||||
template: '<md-dialog>',
|
||||
parent: parent,
|
||||
clickOutsideToClose: false
|
||||
});
|
||||
|
||||
$rootScope.$apply();
|
||||
expect(parent.find('md-dialog').length).toBe(1);
|
||||
|
||||
var container = angular.element(parent[0].querySelector('.md-dialog-container'));
|
||||
|
||||
container.triggerHandler('click');
|
||||
$timeout.flush();
|
||||
$animate.triggerCallbacks();
|
||||
|
||||
expect(parent[0].querySelectorAll('md-dialog').length).toBe(1);
|
||||
}));
|
||||
|
||||
it('should disableParentScroll == true', inject(function($mdDialog, $animate, $rootScope) {
|
||||
var parent = angular.element('<div>');
|
||||
$mdDialog.show({
|
||||
template: '<md-dialog>',
|
||||
parent: parent,
|
||||
disableParentScroll: true
|
||||
});
|
||||
$rootScope.$apply();
|
||||
$animate.triggerCallbacks();
|
||||
$rootScope.$apply();
|
||||
expect(parent.css('overflow')).toBe('hidden');
|
||||
}));
|
||||
|
||||
it('should hasBackdrop == true', inject(function($mdDialog, $animate, $rootScope) {
|
||||
var parent = angular.element('<div>');
|
||||
$mdDialog.show({
|
||||
template: '<md-dialog>',
|
||||
parent: parent,
|
||||
hasBackdrop: true
|
||||
});
|
||||
|
||||
$rootScope.$apply();
|
||||
$animate.triggerCallbacks();
|
||||
$rootScope.$apply();
|
||||
expect(parent.find('md-dialog').length).toBe(1);
|
||||
expect(parent.find('md-backdrop').length).toBe(1);
|
||||
}));
|
||||
|
||||
it('should hasBackdrop == false', inject(function($mdDialog, $rootScope) {
|
||||
var parent = angular.element('<div>');
|
||||
$mdDialog.show({
|
||||
template: '<md-dialog>',
|
||||
parent: parent,
|
||||
hasBackdrop: false
|
||||
});
|
||||
|
||||
$rootScope.$apply();
|
||||
expect(parent[0].querySelectorAll('md-dialog').length).toBe(1);
|
||||
expect(parent[0].querySelectorAll('md-backdrop').length).toBe(0);
|
||||
}));
|
||||
|
||||
it('should focus `md-button.dialog-close` on open', inject(function($mdDialog, $rootScope, $document, $timeout, $mdConstant) {
|
||||
TestUtil.mockElementFocus(this);
|
||||
|
||||
var parent = angular.element('<div>');
|
||||
$mdDialog.show({
|
||||
template:
|
||||
'<md-dialog>' +
|
||||
'<div class="md-actions">' +
|
||||
'<button class="dialog-close">Close</button>' +
|
||||
'</div>' +
|
||||
'</md-dialog>',
|
||||
parent: parent
|
||||
});
|
||||
|
||||
$rootScope.$apply();
|
||||
$timeout.flush();
|
||||
var container = angular.element(parent[0].querySelector('.md-dialog-container'));
|
||||
container.triggerHandler('transitionend');
|
||||
$rootScope.$apply();
|
||||
parent.find('md-dialog').triggerHandler('transitionend');
|
||||
$rootScope.$apply();
|
||||
|
||||
|
||||
expect($document.activeElement).toBe(parent[0].querySelector('.dialog-close'));
|
||||
}));
|
||||
|
||||
it('should focus the last `md-button` in md-actions open if no `.dialog-close`', inject(function($mdDialog, $rootScope, $document, $timeout, $mdConstant) {
|
||||
TestUtil.mockElementFocus(this);
|
||||
|
||||
var parent = angular.element('<div>');
|
||||
$mdDialog.show({
|
||||
template:
|
||||
'<md-dialog>' +
|
||||
'<div class="md-actions">' +
|
||||
'<button id="a">A</md-button>' +
|
||||
'<button id="focus-target">B</md-button>' +
|
||||
'</div>' +
|
||||
'</md-dialog>',
|
||||
parent: parent
|
||||
});
|
||||
|
||||
$rootScope.$apply();
|
||||
$timeout.flush();
|
||||
|
||||
var container = angular.element(parent[0].querySelector('.md-dialog-container'));
|
||||
container.triggerHandler('transitionend');
|
||||
$rootScope.$apply();
|
||||
parent.find('md-dialog').triggerHandler('transitionend');
|
||||
$rootScope.$apply();
|
||||
|
||||
expect($document.activeElement).toBe(parent[0].querySelector('#focus-target'));
|
||||
}));
|
||||
|
||||
it('should only allow one open at a time', inject(function($mdDialog, $rootScope) {
|
||||
var parent = angular.element('<div>');
|
||||
$mdDialog.show({
|
||||
template: '<md-dialog class="one">',
|
||||
parent: parent
|
||||
});
|
||||
|
||||
$rootScope.$apply();
|
||||
expect(parent[0].querySelectorAll('md-dialog.one').length).toBe(1);
|
||||
expect(parent[0].querySelectorAll('md-dialog.two').length).toBe(0);
|
||||
|
||||
$mdDialog.show({
|
||||
template: '<md-dialog class="two">',
|
||||
parent: parent
|
||||
});
|
||||
|
||||
$rootScope.$apply();
|
||||
parent.find('md-dialog').triggerHandler('transitionend');
|
||||
$rootScope.$apply();
|
||||
expect(parent[0].querySelectorAll('md-dialog.one').length).toBe(0);
|
||||
expect(parent[0].querySelectorAll('md-dialog.two').length).toBe(1);
|
||||
}));
|
||||
|
||||
it('should have the dialog role', inject(function($mdDialog, $rootScope) {
|
||||
var template = '<md-dialog>Hello</md-dialog>';
|
||||
var parent = angular.element('<div>');
|
||||
|
||||
$mdDialog.show({
|
||||
template: template,
|
||||
parent: parent
|
||||
});
|
||||
|
||||
$rootScope.$apply();
|
||||
|
||||
var dialog = angular.element(parent[0].querySelectorAll('md-dialog'));
|
||||
expect(dialog.attr('role')).toBe('dialog');
|
||||
}));
|
||||
|
||||
it('should create an ARIA label if one is missing', inject(function($mdDialog, $rootScope) {
|
||||
var template = '<md-dialog>Hello</md-dialog>';
|
||||
var parent = angular.element('<div>');
|
||||
|
||||
$mdDialog.show({
|
||||
template: template,
|
||||
parent: parent
|
||||
});
|
||||
|
||||
$rootScope.$apply();
|
||||
angular.element(parent[0].querySelector('.md-dialog-container')).triggerHandler('transitionend');
|
||||
$rootScope.$apply();
|
||||
|
||||
var dialog = angular.element(parent[0].querySelector('md-dialog'));
|
||||
expect(dialog.attr('aria-label')).toEqual(dialog.text());
|
||||
}));
|
||||
|
||||
it('should not modify an existing ARIA label', inject(function($mdDialog, $rootScope){
|
||||
var template = '<md-dialog aria-label="Some Other Thing">Hello</md-dialog>';
|
||||
var parent = angular.element('<div>');
|
||||
|
||||
$mdDialog.show({
|
||||
template: template,
|
||||
parent: parent
|
||||
});
|
||||
|
||||
$rootScope.$apply();
|
||||
|
||||
var dialog = angular.element(parent[0].querySelector('md-dialog'));
|
||||
expect(dialog.attr('aria-label')).not.toEqual(dialog.text());
|
||||
expect(dialog.attr('aria-label')).toEqual('Some Other Thing');
|
||||
}));
|
||||
});
|
||||
|
||||
function hasConfigurationMethods(preset, methods) {
|
||||
angular.forEach(methods, function(method) {
|
||||
return it('supports config method #' + method, inject(function($mdDialog) {
|
||||
var dialog = $mdDialog[preset]();
|
||||
expect(typeof dialog[method]).toBe('function');
|
||||
expect(dialog[method]()).toEqual(dialog);
|
||||
}));
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('$mdDialog with custom interpolation symbols', function() {
|
||||
beforeEach(TestUtil.mockRaf);
|
||||
beforeEach(module('material.components.dialog', 'ngAnimateMock'));
|
||||
|
||||
beforeEach(module(function($interpolateProvider) {
|
||||
$interpolateProvider.startSymbol('[[').endSymbol(']]');
|
||||
}));
|
||||
|
||||
it('displays #alert() correctly', inject(function($mdDialog, $rootScope) {
|
||||
var parent = angular.element('<div>');
|
||||
var dialog = $mdDialog.
|
||||
alert({parent: parent}).
|
||||
ariaLabel('test alert').
|
||||
title('Title').
|
||||
content('Hello, world !').
|
||||
ok('OK');
|
||||
|
||||
$mdDialog.show(dialog);
|
||||
$rootScope.$digest();
|
||||
|
||||
var mdContainer = angular.element(parent[0].querySelector('.md-dialog-container'));
|
||||
var mdDialog = mdContainer.find('md-dialog');
|
||||
var mdContent = mdDialog.find('md-content');
|
||||
var title = mdContent.find('h2');
|
||||
var content = mdContent.find('p');
|
||||
var mdActions = angular.element(mdDialog[0].querySelector('.md-actions'));
|
||||
var buttons = mdActions.find('md-button');
|
||||
|
||||
expect(mdDialog.attr('aria-label')).toBe('test alert');
|
||||
expect(title.text()).toBe('Title');
|
||||
expect(content.text()).toBe('Hello, world !');
|
||||
expect(buttons.eq(0).text()).toBe('OK');
|
||||
}));
|
||||
|
||||
it('displays #confirm() correctly', inject(function($mdDialog, $rootScope) {
|
||||
var parent = angular.element('<div>');
|
||||
var dialog = $mdDialog.
|
||||
confirm({parent: parent}).
|
||||
ariaLabel('test alert').
|
||||
title('Title').
|
||||
content('Hello, world !').
|
||||
cancel('CANCEL').
|
||||
ok('OK');
|
||||
|
||||
$mdDialog.show(dialog);
|
||||
$rootScope.$digest();
|
||||
|
||||
var mdContainer = angular.element(parent[0].querySelector('.md-dialog-container'));
|
||||
var mdDialog = mdContainer.find('md-dialog');
|
||||
var mdContent = mdDialog.find('md-content');
|
||||
var title = mdContent.find('h2');
|
||||
var content = mdContent.find('p');
|
||||
var mdActions = angular.element(mdDialog[0].querySelector('.md-actions'));
|
||||
var buttons = mdActions.find('md-button');
|
||||
|
||||
expect(mdDialog.attr('aria-label')).toBe('test alert');
|
||||
expect(title.text()).toBe('Title');
|
||||
expect(content.text()).toBe('Hello, world !');
|
||||
expect(buttons.eq(0).text()).toBe('CANCEL');
|
||||
expect(buttons.eq(1).text()).toBe('OK');
|
||||
}));
|
||||
});
|
||||
|
||||
51
UI/WebServerResources/scss/vendors/angular-material/components/divider/demoBasicUsage/index.html
vendored
Normal file
51
UI/WebServerResources/scss/vendors/angular-material/components/divider/demoBasicUsage/index.html
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
<div ng-controller="AppCtrl">
|
||||
|
||||
<md-toolbar class="md-theme-light">
|
||||
<h1 class="md-toolbar-tools">
|
||||
<span>Full Bleed</span>
|
||||
</h1>
|
||||
</md-toolbar>
|
||||
|
||||
<md-content>
|
||||
<md-list>
|
||||
<md-item ng-repeat="item in messages">
|
||||
<md-item-content>
|
||||
<div class="md-tile-content">
|
||||
<h3>{{item.what}}</h3>
|
||||
<h4>{{item.who}}</h4>
|
||||
<p>
|
||||
{{item.notes}}
|
||||
</p>
|
||||
</div>
|
||||
</md-item-content>
|
||||
<md-divider ng-if="!$last"></md-divider>
|
||||
</md-item>
|
||||
</md-list>
|
||||
</md-content>
|
||||
|
||||
<md-toolbar class="md-theme-light">
|
||||
<h1 class="md-toolbar-tools">
|
||||
<span>Inset</span>
|
||||
</h1>
|
||||
</md-toolbar>
|
||||
|
||||
<md-content>
|
||||
<md-list>
|
||||
<md-item ng-repeat="item in messages">
|
||||
<md-item-content>
|
||||
<div class="md-tile-left">
|
||||
<img ng-src="{{item.face}}" class="face" alt="{{item.who}}">
|
||||
</div>
|
||||
<div class="md-tile-content">
|
||||
<h3>{{item.what}}</h3>
|
||||
<h4>{{item.who}}</h4>
|
||||
<p>
|
||||
{{item.notes}}
|
||||
</p>
|
||||
</div>
|
||||
</md-item-content>
|
||||
<md-divider md-inset ng-if="!$last"></md-divider>
|
||||
</md-item>
|
||||
</md-list>
|
||||
</md-content>
|
||||
</div>
|
||||
34
UI/WebServerResources/scss/vendors/angular-material/components/divider/demoBasicUsage/script.js
vendored
Normal file
34
UI/WebServerResources/scss/vendors/angular-material/components/divider/demoBasicUsage/script.js
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
angular.module('dividerDemo1', ['ngMaterial'])
|
||||
.controller('AppCtrl', function($scope) {
|
||||
$scope.messages = [{
|
||||
face: '/img/list/60.jpeg',
|
||||
what: 'Brunch this weekend?',
|
||||
who: 'Min Li Chan',
|
||||
when: '3:08PM',
|
||||
notes: " I'll be in your neighborhood doing errands"
|
||||
}, {
|
||||
face: '/img/list/60.jpeg',
|
||||
what: 'Brunch this weekend?',
|
||||
who: 'Min Li Chan',
|
||||
when: '3:08PM',
|
||||
notes: " I'll be in your neighborhood doing errands"
|
||||
}, {
|
||||
face: '/img/list/60.jpeg',
|
||||
what: 'Brunch this weekend?',
|
||||
who: 'Min Li Chan',
|
||||
when: '3:08PM',
|
||||
notes: " I'll be in your neighborhood doing errands"
|
||||
}, {
|
||||
face: '/img/list/60.jpeg',
|
||||
what: 'Brunch this weekend?',
|
||||
who: 'Min Li Chan',
|
||||
when: '3:08PM',
|
||||
notes: " I'll be in your neighborhood doing errands"
|
||||
}, {
|
||||
face: '/img/list/60.jpeg',
|
||||
what: 'Brunch this weekend?',
|
||||
who: 'Min Li Chan',
|
||||
when: '3:08PM',
|
||||
notes: " I'll be in your neighborhood doing errands"
|
||||
}];
|
||||
});
|
||||
@@ -0,0 +1,6 @@
|
||||
.face {
|
||||
border-radius: 30px;
|
||||
border: 1px solid #ddd;
|
||||
width: 48px;
|
||||
margin: 16px;
|
||||
}
|
||||
3
UI/WebServerResources/scss/vendors/angular-material/components/divider/divider-theme.scss
vendored
Normal file
3
UI/WebServerResources/scss/vendors/angular-material/components/divider/divider-theme.scss
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
md-divider.md-THEME_NAME-theme {
|
||||
border-top-color: '{{foreground-4}}';
|
||||
}
|
||||
41
UI/WebServerResources/scss/vendors/angular-material/components/divider/divider.js
vendored
Normal file
41
UI/WebServerResources/scss/vendors/angular-material/components/divider/divider.js
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc module
|
||||
* @name material.components.divider
|
||||
* @description Divider module!
|
||||
*/
|
||||
angular.module('material.components.divider', [
|
||||
'material.core'
|
||||
])
|
||||
.directive('mdDivider', MdDividerDirective);
|
||||
|
||||
function MdDividerController(){}
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name mdDivider
|
||||
* @module material.components.divider
|
||||
* @restrict E
|
||||
*
|
||||
* @description
|
||||
* Dividers group and separate content within lists and page layouts using strong visual and spatial distinctions. This divider is a thin rule, lightweight enough to not distract the user from content.
|
||||
*
|
||||
* @param {boolean=} md-inset Add this attribute to activate the inset divider style.
|
||||
* @usage
|
||||
* <hljs lang="html">
|
||||
* <md-divider></md-divider>
|
||||
*
|
||||
* <md-divider md-inset></md-divider>
|
||||
* </hljs>
|
||||
*
|
||||
*/
|
||||
function MdDividerDirective($mdTheming) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
link: $mdTheming,
|
||||
controller: [MdDividerController]
|
||||
};
|
||||
}
|
||||
})();
|
||||
9
UI/WebServerResources/scss/vendors/angular-material/components/divider/divider.scss
vendored
Normal file
9
UI/WebServerResources/scss/vendors/angular-material/components/divider/divider.scss
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
md-divider {
|
||||
display: block;
|
||||
border-top: 1px solid;
|
||||
margin: 0;
|
||||
|
||||
&[md-inset] {
|
||||
margin-left: $baseline-grid * 9; // fix for vs-repeat
|
||||
}
|
||||
}
|
||||
44
UI/WebServerResources/scss/vendors/angular-material/components/icon/icon.js
vendored
Normal file
44
UI/WebServerResources/scss/vendors/angular-material/components/icon/icon.js
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
/*
|
||||
* @ngdoc module
|
||||
* @name material.components.icon
|
||||
* @description
|
||||
* Icon
|
||||
*/
|
||||
angular.module('material.components.icon', [
|
||||
'material.core'
|
||||
])
|
||||
.directive('mdIcon', mdIconDirective);
|
||||
|
||||
/*
|
||||
* @ngdoc directive
|
||||
* @name mdIcon
|
||||
* @module material.components.icon
|
||||
*
|
||||
* @restrict E
|
||||
*
|
||||
* @description
|
||||
* The `<md-icon>` directive is an element useful for SVG icons
|
||||
*
|
||||
* @usage
|
||||
* <hljs lang="html">
|
||||
* <md-icon icon="/img/icons/ic_access_time_24px.svg">
|
||||
* </md-icon>
|
||||
* </hljs>
|
||||
*
|
||||
*/
|
||||
function mdIconDirective() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
template: '<object class="md-icon"></object>',
|
||||
compile: function(element, attr) {
|
||||
var object = angular.element(element[0].children[0]);
|
||||
if(angular.isDefined(attr.icon)) {
|
||||
object.attr('data', attr.icon);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
})();
|
||||
18
UI/WebServerResources/scss/vendors/angular-material/components/icon/icon.scss
vendored
Normal file
18
UI/WebServerResources/scss/vendors/angular-material/components/icon/icon.scss
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
md-icon {
|
||||
margin: auto;
|
||||
padding: 0;
|
||||
display: inline-block;
|
||||
margin-top: 5px;
|
||||
background-repeat: no-repeat no-repeat;
|
||||
pointer-events: none;
|
||||
}
|
||||
svg, object {
|
||||
fill: currentColor;
|
||||
color: currentColor;
|
||||
}
|
||||
|
||||
md-class-icon {
|
||||
// display: block;
|
||||
// margin: 0 auto;
|
||||
}
|
||||
2
UI/WebServerResources/scss/vendors/angular-material/components/icon/icon.spec.js
vendored
Normal file
2
UI/WebServerResources/scss/vendors/angular-material/components/icon/icon.spec.js
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
describe('mdIcon directive', function() {
|
||||
});
|
||||
58
UI/WebServerResources/scss/vendors/angular-material/components/input/demoBasicUsage/index.html
vendored
Normal file
58
UI/WebServerResources/scss/vendors/angular-material/components/input/demoBasicUsage/index.html
vendored
Normal 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>
|
||||
16
UI/WebServerResources/scss/vendors/angular-material/components/input/demoBasicUsage/script.js
vendored
Normal file
16
UI/WebServerResources/scss/vendors/angular-material/components/input/demoBasicUsage/script.js
vendored
Normal 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'
|
||||
};
|
||||
});
|
||||
50
UI/WebServerResources/scss/vendors/angular-material/components/input/input-theme.scss
vendored
Normal file
50
UI/WebServerResources/scss/vendors/angular-material/components/input/input-theme.scss
vendored
Normal 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%);
|
||||
}
|
||||
}
|
||||
189
UI/WebServerResources/scss/vendors/angular-material/components/input/input.js
vendored
Normal file
189
UI/WebServerResources/scss/vendors/angular-material/components/input/input.js
vendored
Normal 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';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
||||
93
UI/WebServerResources/scss/vendors/angular-material/components/input/input.scss
vendored
Normal file
93
UI/WebServerResources/scss/vendors/angular-material/components/input/input.scss
vendored
Normal 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;
|
||||
}
|
||||
}
|
||||
58
UI/WebServerResources/scss/vendors/angular-material/components/input/input.spec.js
vendored
Normal file
58
UI/WebServerResources/scss/vendors/angular-material/components/input/input.spec.js
vendored
Normal 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'));
|
||||
}));
|
||||
});
|
||||
25
UI/WebServerResources/scss/vendors/angular-material/components/list/demoBasicUsage/index.html
vendored
Normal file
25
UI/WebServerResources/scss/vendors/angular-material/components/list/demoBasicUsage/index.html
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
<div ng-controller="AppCtrl">
|
||||
<md-content>
|
||||
|
||||
<md-list>
|
||||
|
||||
<md-item ng-repeat="item in todos">
|
||||
<md-item-content>
|
||||
<div class="md-tile-left">
|
||||
<img ng-src="{{item.face}}" class="face" alt="{{item.who}}">
|
||||
</div>
|
||||
<div class="md-tile-content">
|
||||
<h3>{{item.what}}</h3>
|
||||
<h4>{{item.who}}</h4>
|
||||
<p>
|
||||
{{item.notes}}
|
||||
</p>
|
||||
</div>
|
||||
</md-item-content>
|
||||
</md-item>
|
||||
|
||||
</md-list>
|
||||
|
||||
</md-content>
|
||||
</div>
|
||||
44
UI/WebServerResources/scss/vendors/angular-material/components/list/demoBasicUsage/script.js
vendored
Normal file
44
UI/WebServerResources/scss/vendors/angular-material/components/list/demoBasicUsage/script.js
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
|
||||
angular.module('listDemo1', ['ngMaterial'])
|
||||
|
||||
.controller('AppCtrl', function($scope) {
|
||||
$scope.todos = [
|
||||
{
|
||||
face : '/img/list/60.jpeg',
|
||||
what: 'Brunch this weekend?',
|
||||
who: 'Min Li Chan',
|
||||
when: '3:08PM',
|
||||
notes: " I'll be in your neighborhood doing errands"
|
||||
},
|
||||
{
|
||||
face : '/img/list/60.jpeg',
|
||||
what: 'Brunch this weekend?',
|
||||
who: 'Min Li Chan',
|
||||
when: '3:08PM',
|
||||
notes: " I'll be in your neighborhood doing errands"
|
||||
},
|
||||
{
|
||||
face : '/img/list/60.jpeg',
|
||||
what: 'Brunch this weekend?',
|
||||
who: 'Min Li Chan',
|
||||
when: '3:08PM',
|
||||
notes: " I'll be in your neighborhood doing errands"
|
||||
},
|
||||
{
|
||||
face : '/img/list/60.jpeg',
|
||||
what: 'Brunch this weekend?',
|
||||
who: 'Min Li Chan',
|
||||
when: '3:08PM',
|
||||
notes: " I'll be in your neighborhood doing errands"
|
||||
},
|
||||
{
|
||||
face : '/img/list/60.jpeg',
|
||||
what: 'Brunch this weekend?',
|
||||
who: 'Min Li Chan',
|
||||
when: '3:08PM',
|
||||
notes: " I'll be in your neighborhood doing errands"
|
||||
},
|
||||
]
|
||||
|
||||
});
|
||||
|
||||
7
UI/WebServerResources/scss/vendors/angular-material/components/list/demoBasicUsage/style.css
vendored
Normal file
7
UI/WebServerResources/scss/vendors/angular-material/components/list/demoBasicUsage/style.css
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
.face {
|
||||
border-radius: 30px;
|
||||
border: 1px solid #ddd;
|
||||
width: 48px;
|
||||
margin: 16px;
|
||||
}
|
||||
88
UI/WebServerResources/scss/vendors/angular-material/components/list/list.js
vendored
Normal file
88
UI/WebServerResources/scss/vendors/angular-material/components/list/list.js
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc module
|
||||
* @name material.components.list
|
||||
* @description
|
||||
* List module
|
||||
*/
|
||||
angular.module('material.components.list', [
|
||||
'material.core'
|
||||
])
|
||||
.directive('mdList', mdListDirective)
|
||||
.directive('mdItem', mdItemDirective);
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name mdList
|
||||
* @module material.components.list
|
||||
*
|
||||
* @restrict E
|
||||
*
|
||||
* @description
|
||||
* The `<md-list>` directive is a list container for 1..n `<md-item>` tags.
|
||||
*
|
||||
* @usage
|
||||
* <hljs lang="html">
|
||||
* <md-list>
|
||||
* <md-item ng-repeat="item in todos">
|
||||
* <md-item-content>
|
||||
* <div class="md-tile-left">
|
||||
* <img ng-src="{{item.face}}" class="face" alt="{{item.who}}">
|
||||
* </div>
|
||||
* <div class="md-tile-content">
|
||||
* <h3>{{item.what}}</h3>
|
||||
* <h4>{{item.who}}</h4>
|
||||
* <p>
|
||||
* {{item.notes}}
|
||||
* </p>
|
||||
* </div>
|
||||
* </md-item-content>
|
||||
* </md-item>
|
||||
* </md-list>
|
||||
* </hljs>
|
||||
*
|
||||
*/
|
||||
function mdListDirective() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
link: function($scope, $element, $attr) {
|
||||
$element.attr({
|
||||
'role' : 'list'
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name mdItem
|
||||
* @module material.components.list
|
||||
*
|
||||
* @restrict E
|
||||
*
|
||||
* @description
|
||||
* The `<md-item>` directive is a container intended for row items in a `<md-list>` container.
|
||||
*
|
||||
* @usage
|
||||
* <hljs lang="html">
|
||||
* <md-list>
|
||||
* <md-item>
|
||||
* Item content in list
|
||||
* </md-item>
|
||||
* </md-list>
|
||||
* </hljs>
|
||||
*
|
||||
*/
|
||||
function mdItemDirective() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
link: function($scope, $element, $attr) {
|
||||
$element.attr({
|
||||
'role' : 'listitem'
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
})();
|
||||
103
UI/WebServerResources/scss/vendors/angular-material/components/list/list.scss
vendored
Normal file
103
UI/WebServerResources/scss/vendors/angular-material/components/list/list.scss
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
$list-h3-font-size: 1.1em !default;
|
||||
$list-h3-margin: 0 0 3px 0 !default;
|
||||
$list-h3-font-weight: 400 !default;
|
||||
$list-h4-font-size: 0.9em !default;
|
||||
$list-h4-font-weight: 400 !default;
|
||||
$list-h4-margin: 0 0 3px 0 !default;
|
||||
$list-p-font-size: 0.75em !default;
|
||||
$list-p-margin: 0 0 3px 0 !default;
|
||||
|
||||
$list-padding-top: $baseline-grid !default;
|
||||
$list-padding-right: 0px !default;
|
||||
$list-padding-left: 0px !default;
|
||||
$list-padding-bottom: $baseline-grid !default;
|
||||
|
||||
$item-padding-top: 0px !default;
|
||||
$item-padding-right: 0px !default;
|
||||
$item-padding-left: 0px !default;
|
||||
$item-padding-bottom: 0px !default;
|
||||
|
||||
md-list {
|
||||
padding: $list-padding-top $list-padding-right $list-padding-bottom $list-padding-left;
|
||||
}
|
||||
|
||||
md-item {
|
||||
|
||||
}
|
||||
|
||||
md-item-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
box-sizing: border-box;
|
||||
|
||||
position: relative;
|
||||
|
||||
padding: $item-padding-top $item-padding-right $item-padding-bottom $item-padding-left;
|
||||
}
|
||||
|
||||
/**
|
||||
* The left tile for a list item.
|
||||
*/
|
||||
.md-tile-left {
|
||||
min-width: 56px;
|
||||
margin-right: -16px;
|
||||
// for dev only
|
||||
height: 56px;
|
||||
background-color: grey;
|
||||
}
|
||||
|
||||
/**
|
||||
* The center content tile for a list item.
|
||||
*/
|
||||
.md-tile-content {
|
||||
flex: 1;
|
||||
|
||||
padding: $baseline-grid * 2;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
h3 {
|
||||
margin: $list-h3-margin;
|
||||
font-weight: $list-h3-font-weight;
|
||||
font-size: $list-h3-font-size;
|
||||
}
|
||||
h4 {
|
||||
margin: $list-h4-margin;
|
||||
font-weight: $list-h4-font-weight;
|
||||
font-size: $list-h4-font-size;
|
||||
}
|
||||
p {
|
||||
margin: $list-p-margin;
|
||||
font-size: $list-p-font-size;
|
||||
}
|
||||
}
|
||||
.sg {
|
||||
&-tile-content {
|
||||
@extend .md-tile-content;
|
||||
margin-left: $layout-gutter-width; // dirty fix for vs-repeat damages
|
||||
.name {
|
||||
margin: $list-h3-margin;
|
||||
font-weight: $list-h3-font-weight;
|
||||
font-size: $list-h3-font-size;
|
||||
}
|
||||
.subject {
|
||||
margin: $list-h4-margin;
|
||||
font-weight: $list-h4-font-weight;
|
||||
font-size: $list-h4-font-size;
|
||||
// dirty fix for vs-repeat damages
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
p {
|
||||
margin: $list-p-margin;
|
||||
font-size: $list-p-font-size;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* The right tile for a list item.
|
||||
*/
|
||||
.md-tile-right {
|
||||
padding-right: $item-padding-right;
|
||||
}
|
||||
11
UI/WebServerResources/scss/vendors/angular-material/components/list/list.spec.js
vendored
Normal file
11
UI/WebServerResources/scss/vendors/angular-material/components/list/list.spec.js
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
describe('mdList directive', function() {
|
||||
function setup(attrs) {
|
||||
module('material.components.list');
|
||||
var el;
|
||||
inject(function($compile, $rootScope) {
|
||||
el = $compile('<md-list '+(attrs || '')+'></md-list>')($rootScope.$new());
|
||||
$rootScope.$apply();
|
||||
});
|
||||
return el;
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,25 @@
|
||||
<div ng-controller="AppCtrl" layout="column" layout-margin style="padding:25px;">
|
||||
|
||||
<h4 style="margin-top:10px">Determinate</h4>
|
||||
<p>For operations where the percentage of the operation completed can be determined, use a determinate indicator. They give users a quick sense of how long an operation will take.</p>
|
||||
<div layout="row" layout-sm="column" layout-align="space-around">
|
||||
<md-progress-circular md-mode="determinate" value="{{determinateValue}}"></md-progress-circular>
|
||||
</div>
|
||||
|
||||
<h4>Indeterminate</h4>
|
||||
<p>For operations where the user is asked to wait a moment while something finishes up, and it’s not necessary to expose what's happening behind the scenes and how long it will take, use an indeterminate indicator.</p>
|
||||
<div layout="row" layout-sm="column" layout-align="space-around">
|
||||
<md-progress-circular md-mode="indeterminate"></md-progress-circular>
|
||||
</div>
|
||||
|
||||
<h4>Theming</h4>
|
||||
|
||||
<div layout="row" layout-sm="column" layout-align="space-around">
|
||||
<md-progress-circular class="md-hue-2" md-mode="indeterminate"></md-progress-circular>
|
||||
<md-progress-circular class="md-accent" md-mode="indeterminate"></md-progress-circular>
|
||||
<md-progress-circular class="md-accent md-hue-1" md-mode="indeterminate"></md-progress-circular>
|
||||
<md-progress-circular class="md-warn md-hue-3" md-mode="indeterminate"></md-progress-circular>
|
||||
<md-progress-circular class="md-warn" md-mode="indeterminate"></md-progress-circular>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,14 @@
|
||||
angular.module('progressCircularDemo1', ['ngMaterial'])
|
||||
.controller('AppCtrl', ['$scope', '$interval',
|
||||
function($scope, $interval) {
|
||||
$scope.mode = 'query';
|
||||
$scope.determinateValue = 30;
|
||||
|
||||
$interval(function() {
|
||||
$scope.determinateValue += 1;
|
||||
if ($scope.determinateValue > 100) {
|
||||
$scope.determinateValue = 30;
|
||||
}
|
||||
}, 100, 0, true);
|
||||
}
|
||||
]);
|
||||
@@ -0,0 +1,11 @@
|
||||
body {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
md-progress-circular {
|
||||
margin-bottom:20px;
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
|
||||
md-progress-circular.md-THEME_NAME-theme {
|
||||
background-color: transparent;
|
||||
.md-inner {
|
||||
.md-gap {
|
||||
border-top-color: '{{primary-color}}';
|
||||
border-bottom-color: '{{primary-color}}';
|
||||
}
|
||||
.md-left, .md-right {
|
||||
.md-half-circle {
|
||||
border-top-color: '{{primary-color}}';
|
||||
}
|
||||
}
|
||||
.md-right {
|
||||
.md-half-circle {
|
||||
border-right-color: '{{primary-color}}';
|
||||
}
|
||||
}
|
||||
.md-left {
|
||||
.md-half-circle {
|
||||
border-left-color: '{{primary-color}}';
|
||||
}
|
||||
}
|
||||
}
|
||||
&.md-warn {
|
||||
.md-inner {
|
||||
.md-gap {
|
||||
border-top-color: '{{warn-color}}';
|
||||
border-bottom-color: '{{warn-color}}';
|
||||
}
|
||||
.md-left, .md-right {
|
||||
.md-half-circle {
|
||||
border-top-color: '{{warn-color}}';
|
||||
}
|
||||
}
|
||||
.md-right {
|
||||
.md-half-circle {
|
||||
border-right-color: '{{warn-color}}';
|
||||
}
|
||||
}
|
||||
.md-left {
|
||||
.md-half-circle {
|
||||
border-left-color: '{{warn-color}}';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&.md-accent {
|
||||
.md-inner {
|
||||
.md-gap {
|
||||
border-top-color: '{{accent-color}}';
|
||||
border-bottom-color: '{{accent-color}}';
|
||||
}
|
||||
.md-left, .md-right {
|
||||
.md-half-circle {
|
||||
border-top-color: '{{accent-color}}';
|
||||
}
|
||||
}
|
||||
.md-right {
|
||||
.md-half-circle {
|
||||
border-right-color: '{{accent-color}}';
|
||||
}
|
||||
}
|
||||
.md-left {
|
||||
.md-half-circle {
|
||||
border-left-color: '{{accent-color}}';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
120
UI/WebServerResources/scss/vendors/angular-material/components/progressCircular/progressCircular.js
vendored
Normal file
120
UI/WebServerResources/scss/vendors/angular-material/components/progressCircular/progressCircular.js
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc module
|
||||
* @name material.components.progressCircular
|
||||
* @description Circular Progress module!
|
||||
*/
|
||||
angular.module('material.components.progressCircular', [
|
||||
'material.core'
|
||||
])
|
||||
.directive('mdProgressCircular', MdProgressCircularDirective);
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name mdProgressCircular
|
||||
* @module material.components.progressCircular
|
||||
* @restrict E
|
||||
*
|
||||
* @description
|
||||
* The circular progress directive is used to make loading content in your app as delightful and painless as possible by minimizing the amount of visual change a user sees before they can view and interact with content.
|
||||
*
|
||||
* For operations where the percentage of the operation completed can be determined, use a determinate indicator. They give users a quick sense of how long an operation will take.
|
||||
*
|
||||
* For operations where the user is asked to wait a moment while something finishes up, and it’s not necessary to expose what's happening behind the scenes and how long it will take, use an indeterminate indicator.
|
||||
*
|
||||
* @param {string} md-mode Select from one of two modes: determinate and indeterminate.
|
||||
* @param {number=} value In determinate mode, this number represents the percentage of the circular progress. Default: 0
|
||||
* @param {number=} md-diameter This specifies the diamter of the circular progress. Default: 48
|
||||
*
|
||||
* @usage
|
||||
* <hljs lang="html">
|
||||
* <md-progress-circular md-mode="determinate" value="..."></md-progress-circular>
|
||||
*
|
||||
* <md-progress-circular md-mode="determinate" ng-value="..."></md-progress-circular>
|
||||
*
|
||||
* <md-progress-circular md-mode="determinate" value="..." md-diameter="100"></md-progress-circular>
|
||||
*
|
||||
* <md-progress-circular md-mode="indeterminate"></md-progress-circular>
|
||||
* </hljs>
|
||||
*/
|
||||
function MdProgressCircularDirective($$rAF, $mdConstant, $mdTheming) {
|
||||
var fillRotations = new Array(101),
|
||||
fixRotations = new Array(101);
|
||||
|
||||
for (var i = 0; i < 101; i++) {
|
||||
var percent = i / 100;
|
||||
var rotation = Math.floor(percent * 180);
|
||||
|
||||
fillRotations[i] = 'rotate(' + rotation.toString() + 'deg)';
|
||||
fixRotations[i] = 'rotate(' + (rotation * 2).toString() + 'deg)';
|
||||
}
|
||||
|
||||
return {
|
||||
restrict: 'E',
|
||||
template:
|
||||
'<div class="md-spinner-wrapper">' +
|
||||
'<div class="md-inner">' +
|
||||
'<div class="md-gap"></div>' +
|
||||
'<div class="md-left">' +
|
||||
'<div class="md-half-circle"></div>' +
|
||||
'</div>' +
|
||||
'<div class="md-right">' +
|
||||
'<div class="md-half-circle"></div>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'</div>',
|
||||
compile: compile
|
||||
};
|
||||
|
||||
function compile(tElement, tAttrs, transclude) {
|
||||
tElement.attr('aria-valuemin', 0);
|
||||
tElement.attr('aria-valuemax', 100);
|
||||
tElement.attr('role', 'progressbar');
|
||||
|
||||
return postLink;
|
||||
}
|
||||
|
||||
function postLink(scope, element, attr) {
|
||||
$mdTheming(element);
|
||||
var circle = element[0],
|
||||
fill = circle.querySelectorAll('.md-fill, .md-mask.md-full'),
|
||||
fix = circle.querySelectorAll('.md-fill.md-fix'),
|
||||
i, clamped, fillRotation, fixRotation;
|
||||
|
||||
var diameter = attr.mdDiameter || 48;
|
||||
var scale = diameter/48;
|
||||
|
||||
circle.style[$mdConstant.CSS.TRANSFORM] = 'scale(' + scale.toString() + ')';
|
||||
|
||||
attr.$observe('value', function(value) {
|
||||
clamped = clamp(value);
|
||||
fillRotation = fillRotations[clamped];
|
||||
fixRotation = fixRotations[clamped];
|
||||
|
||||
element.attr('aria-valuenow', clamped);
|
||||
|
||||
for (i = 0; i < fill.length; i++) {
|
||||
fill[i].style[$mdConstant.CSS.TRANSFORM] = fillRotation;
|
||||
}
|
||||
|
||||
for (i = 0; i < fix.length; i++) {
|
||||
fix[i].style[$mdConstant.CSS.TRANSFORM] = fixRotation;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function clamp(value) {
|
||||
if (value > 100) {
|
||||
return 100;
|
||||
}
|
||||
|
||||
if (value < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Math.ceil(value || 0);
|
||||
}
|
||||
}
|
||||
})();
|
||||
@@ -0,0 +1,159 @@
|
||||
$progress-circular-ease-in-out : cubic-bezier(0.35, 0, 0.25, 1) !default;
|
||||
$progress-circular-duration : 5.25s !default;
|
||||
$progress-circular-circle-duration : $progress-circular-duration * 0.25 !default;
|
||||
$progress-circular-outer-duration : $progress-circular-duration * (5 / 9) !default;
|
||||
$progress-circular-sporadic-duration : $progress-circular-duration !default;
|
||||
$progress-circular-size : 50px !default;
|
||||
|
||||
@keyframes outer-rotate {
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
@keyframes left-wobble {
|
||||
0%, 100% { transform: rotate(130deg); }
|
||||
50% { transform: rotate( -5deg); }
|
||||
}
|
||||
@keyframes right-wobble {
|
||||
0%, 100% { transform: rotate(-130deg); }
|
||||
50% { transform: rotate( 5deg); }
|
||||
}
|
||||
@keyframes sporadic-rotate {
|
||||
12.5% { transform: rotate( 135deg); }
|
||||
25% { transform: rotate( 270deg); }
|
||||
37.5% { transform: rotate( 405deg); }
|
||||
50% { transform: rotate( 540deg); }
|
||||
62.5% { transform: rotate( 675deg); }
|
||||
75% { transform: rotate( 810deg); }
|
||||
87.5% { transform: rotate( 945deg); }
|
||||
100% { transform: rotate(1080deg); }
|
||||
}
|
||||
|
||||
md-progress-circular {
|
||||
width: $progress-circular-size;
|
||||
height: $progress-circular-size;
|
||||
display: block;
|
||||
position: relative;
|
||||
padding-top: 0 !important;
|
||||
margin-bottom: 0 !important;
|
||||
overflow: hidden;
|
||||
.md-inner {
|
||||
width: $progress-circular-size;
|
||||
height: $progress-circular-size;
|
||||
position: relative;
|
||||
.md-gap {
|
||||
position: absolute;
|
||||
left: $progress-circular-size * 0.5 - 1;
|
||||
right: $progress-circular-size * 0.5 - 1;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
border-top: 5px solid black;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.md-left, .md-right {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
height: $progress-circular-size;
|
||||
width: $progress-circular-size * 0.5;
|
||||
overflow: hidden;
|
||||
.md-half-circle {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: $progress-circular-size;
|
||||
height: $progress-circular-size;
|
||||
box-sizing: border-box;
|
||||
border-width: 5px;
|
||||
border-style: solid;
|
||||
border-color: black black transparent;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
.md-left {
|
||||
left: 0;
|
||||
.md-half-circle {
|
||||
left: 0;
|
||||
border-right-color: transparent;
|
||||
}
|
||||
}
|
||||
.md-right {
|
||||
right: 0;
|
||||
.md-half-circle {
|
||||
right: 0;
|
||||
border-left-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$i: 0;
|
||||
@while $i <= 100 {
|
||||
&[value="#{$i}"] {
|
||||
.md-inner {
|
||||
.md-left {
|
||||
.md-half-circle {
|
||||
@if $i <= 50 {
|
||||
transform: rotate(135deg);
|
||||
} @else {
|
||||
transition: transform 0.1s linear;
|
||||
$deg: ($i - 50) / 50 * 180 + 135;
|
||||
transform: rotate(#{$deg}deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
.md-right {
|
||||
.md-half-circle {
|
||||
@if $i <= 50 {
|
||||
transition: transform 0.1s linear;
|
||||
$deg: $i / 50 * 180 - 135;
|
||||
transform: rotate(#{$deg}deg);
|
||||
} @else {
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
.md-gap {
|
||||
border-bottom-width: 5px;
|
||||
border-bottom-style: solid;
|
||||
@if $i <= 50 {
|
||||
border-bottom-color: transparent !important;
|
||||
} @else {
|
||||
transition: border-bottom-color 0.1s linear;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$i: $i + 1;
|
||||
}
|
||||
|
||||
&:not([md-mode=indeterminate]) {
|
||||
.md-inner {
|
||||
.md-left, .md-right {
|
||||
.md-half-circle {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&[md-mode=indeterminate] {
|
||||
.md-spinner-wrapper {
|
||||
animation: outer-rotate $progress-circular-outer-duration linear infinite;
|
||||
.md-inner {
|
||||
animation: sporadic-rotate $progress-circular-sporadic-duration $progress-circular-ease-in-out infinite;
|
||||
.md-left, .md-right {
|
||||
.md-half-circle {
|
||||
animation-iteration-count: infinite;
|
||||
animation-duration: ($progress-circular-duration * 0.25);
|
||||
animation-timing-function: $progress-circular-ease-in-out;
|
||||
}
|
||||
}
|
||||
.md-left {
|
||||
.md-half-circle {
|
||||
animation-name: left-wobble;
|
||||
}
|
||||
}
|
||||
.md-right {
|
||||
.md-half-circle {
|
||||
animation-name: right-wobble;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
describe('mdProgressCircular', function() {
|
||||
beforeEach(module('material.components.progressCircular'));
|
||||
|
||||
it('should update aria-valuenow', inject(function($compile, $rootScope) {
|
||||
var element = $compile('<div>' +
|
||||
'<md-progress-circular value="{{progress}}">' +
|
||||
'</md-progress-circular>' +
|
||||
'</div>')($rootScope);
|
||||
|
||||
$rootScope.$apply(function() {
|
||||
$rootScope.progress = 50;
|
||||
});
|
||||
|
||||
var progress = element.find('md-progress-circular');
|
||||
|
||||
expect(progress.eq(0).attr('aria-valuenow')).toEqual('50');
|
||||
}));
|
||||
});
|
||||
@@ -0,0 +1,12 @@
|
||||
<div ng-controller="AppCtrl" layout="column" layout-margin style="padding:25px;">
|
||||
|
||||
<md-progress-linear md-mode="indeterminate"></md-progress-linear>
|
||||
|
||||
<md-progress-linear class="md-warn" md-mode="buffer" value="{{determinateValue}}" md-buffer-value="{{determinateValue2}}">
|
||||
</md-progress-linear>
|
||||
|
||||
<md-progress-linear class="md-accent" md-mode="{{mode}}" value="{{determinateValue}}"></md-progress-linear>
|
||||
|
||||
<md-progress-linear md-theme="custom" md-mode="determinate" ng-value="determinateValue" ></md-progress-linear>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,21 @@
|
||||
angular.module('progressLinearDemo1', ['ngMaterial'])
|
||||
.config(function($mdThemingProvider) {
|
||||
})
|
||||
.controller('AppCtrl', ['$scope', '$interval', function($scope, $interval) {
|
||||
$scope.mode = 'query';
|
||||
$scope.determinateValue = 30;
|
||||
$scope.determinateValue2 = 30;
|
||||
|
||||
$interval(function() {
|
||||
$scope.determinateValue += 1;
|
||||
$scope.determinateValue2 += 1.5;
|
||||
if ($scope.determinateValue > 100) {
|
||||
$scope.determinateValue = 30;
|
||||
$scope.determinateValue2 = 30;
|
||||
}
|
||||
}, 100, 0, true);
|
||||
|
||||
$interval(function() {
|
||||
$scope.mode = ($scope.mode == 'query' ? 'determinate' : 'query');
|
||||
}, 7200, 0, true);
|
||||
}]);
|
||||
@@ -0,0 +1,12 @@
|
||||
body {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
md-progress-linear {
|
||||
padding-top:10px;
|
||||
margin-bottom:20px;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
md-progress-linear.md-THEME_NAME-theme {
|
||||
.md-container {
|
||||
background-color: '{{primary-100}}';
|
||||
}
|
||||
|
||||
.md-bar {
|
||||
background-color: '{{primary-color}}';
|
||||
}
|
||||
|
||||
&.md-warn .md-container {
|
||||
background-color: '{{warn-100}}';
|
||||
}
|
||||
|
||||
&.md-warn .md-bar {
|
||||
background-color: '{{warn-color}}';
|
||||
}
|
||||
|
||||
&.md-accent .md-container {
|
||||
background-color: '{{accent-100}}';
|
||||
}
|
||||
|
||||
&.md-accent .md-bar {
|
||||
background-color: '{{accent-color}}';
|
||||
}
|
||||
|
||||
&[md-mode=buffer] {
|
||||
&.md-warn {
|
||||
.md-bar1 {
|
||||
background-color: '{{warn-100}}';
|
||||
}
|
||||
.md-dashed:before {
|
||||
background: radial-gradient('{{warn-100}}' 0%, '{{warn-100}}' 16%, transparent 42%);
|
||||
}
|
||||
}
|
||||
&.md-accent {
|
||||
.md-bar1 {
|
||||
background-color: '{{accent-100}}';
|
||||
}
|
||||
.md-dashed:before {
|
||||
background: radial-gradient('{{accent-100}}' 0%, '{{accent-100}}' 16%, transparent 42%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
121
UI/WebServerResources/scss/vendors/angular-material/components/progressLinear/progressLinear.js
vendored
Normal file
121
UI/WebServerResources/scss/vendors/angular-material/components/progressLinear/progressLinear.js
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
|
||||
/**
|
||||
* @ngdoc module
|
||||
* @name material.components.progressLinear
|
||||
* @description Linear Progress module!
|
||||
*/
|
||||
angular.module('material.components.progressLinear', [
|
||||
'material.core'
|
||||
])
|
||||
.directive('mdProgressLinear', MdProgressLinearDirective);
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name mdProgressLinear
|
||||
* @module material.components.progressLinear
|
||||
* @restrict E
|
||||
*
|
||||
* @description
|
||||
* The linear progress directive is used to make loading content in your app as delightful and painless as possible by minimizing the amount of visual change a user sees before they can view and interact with content. Each operation should only be represented by one activity indicator—for example, one refresh operation should not display both a refresh bar and an activity circle.
|
||||
*
|
||||
* For operations where the percentage of the operation completed can be determined, use a determinate indicator. They give users a quick sense of how long an operation will take.
|
||||
*
|
||||
* For operations where the user is asked to wait a moment while something finishes up, and it’s not necessary to expose what's happening behind the scenes and how long it will take, use an indeterminate indicator.
|
||||
*
|
||||
* @param {string} md-mode Select from one of four modes: determinate, indeterminate, buffer or query.
|
||||
* @param {number=} value In determinate and buffer modes, this number represents the percentage of the primary progress bar. Default: 0
|
||||
* @param {number=} md-buffer-value In the buffer mode, this number represents the precentage of the secondary progress bar. Default: 0
|
||||
*
|
||||
* @usage
|
||||
* <hljs lang="html">
|
||||
* <md-progress-linear md-mode="determinate" value="..."></md-progress-linear>
|
||||
*
|
||||
* <md-progress-linear md-mode="determinate" ng-value="..."></md-progress-linear>
|
||||
*
|
||||
* <md-progress-linear md-mode="indeterminate"></md-progress-linear>
|
||||
*
|
||||
* <md-progress-linear md-mode="buffer" value="..." md-buffer-value="..."></md-progress-linear>
|
||||
*
|
||||
* <md-progress-linear md-mode="query"></md-progress-linear>
|
||||
* </hljs>
|
||||
*/
|
||||
function MdProgressLinearDirective($$rAF, $mdConstant, $mdTheming) {
|
||||
|
||||
return {
|
||||
restrict: 'E',
|
||||
template: '<div class="md-container">' +
|
||||
'<div class="md-dashed"></div>' +
|
||||
'<div class="md-bar md-bar1"></div>' +
|
||||
'<div class="md-bar md-bar2"></div>' +
|
||||
'</div>',
|
||||
compile: compile
|
||||
};
|
||||
|
||||
function compile(tElement, tAttrs, transclude) {
|
||||
tElement.attr('aria-valuemin', 0);
|
||||
tElement.attr('aria-valuemax', 100);
|
||||
tElement.attr('role', 'progressbar');
|
||||
|
||||
return postLink;
|
||||
}
|
||||
function postLink(scope, element, attr) {
|
||||
$mdTheming(element);
|
||||
var bar1Style = element[0].querySelector('.md-bar1').style,
|
||||
bar2Style = element[0].querySelector('.md-bar2').style,
|
||||
container = angular.element(element[0].querySelector('.md-container'));
|
||||
|
||||
attr.$observe('value', function(value) {
|
||||
if (attr.mdMode == 'query') {
|
||||
return;
|
||||
}
|
||||
|
||||
var clamped = clamp(value);
|
||||
element.attr('aria-valuenow', clamped);
|
||||
bar2Style[$mdConstant.CSS.TRANSFORM] = transforms[clamped];
|
||||
});
|
||||
|
||||
attr.$observe('mdBufferValue', function(value) {
|
||||
bar1Style[$mdConstant.CSS.TRANSFORM] = transforms[clamp(value)];
|
||||
});
|
||||
|
||||
$$rAF(function() {
|
||||
container.addClass('md-ready');
|
||||
});
|
||||
}
|
||||
|
||||
function clamp(value) {
|
||||
if (value > 100) {
|
||||
return 100;
|
||||
}
|
||||
|
||||
if (value < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Math.ceil(value || 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// **********************************************************
|
||||
// Private Methods
|
||||
// **********************************************************
|
||||
var transforms = (function() {
|
||||
var values = new Array(101);
|
||||
for(var i = 0; i < 101; i++){
|
||||
values[i] = makeTransform(i);
|
||||
}
|
||||
|
||||
return values;
|
||||
|
||||
function makeTransform(value){
|
||||
var scale = value/100;
|
||||
var translateX = (value-100)/2;
|
||||
return 'translateX(' + translateX.toString() + '%) scale(' + scale.toString() + ', 1)';
|
||||
}
|
||||
})();
|
||||
|
||||
})();
|
||||
201
UI/WebServerResources/scss/vendors/angular-material/components/progressLinear/progressLinear.scss
vendored
Normal file
201
UI/WebServerResources/scss/vendors/angular-material/components/progressLinear/progressLinear.scss
vendored
Normal file
@@ -0,0 +1,201 @@
|
||||
$progress-linear-bar-height:5px !default;
|
||||
|
||||
md-progress-linear {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: $progress-linear-bar-height;
|
||||
|
||||
.md-container {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
height: $progress-linear-bar-height;
|
||||
top: $progress-linear-bar-height;
|
||||
transform: translate(0, 5px) scale(1, 0);
|
||||
transition: all .3s linear;
|
||||
}
|
||||
|
||||
.md-container.md-ready {
|
||||
transform: translate(0, 0) scale(1, 1);
|
||||
}
|
||||
|
||||
.md-bar {
|
||||
height: $progress-linear-bar-height;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.md-bar1, .md-bar2 {
|
||||
transition: all 0.2s linear;
|
||||
}
|
||||
|
||||
&[md-mode=determinate] {
|
||||
.md-bar1 {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&[md-mode=indeterminate] {
|
||||
.md-bar1 {
|
||||
animation: indeterminate1 4s infinite linear;
|
||||
}
|
||||
|
||||
.md-bar2 {
|
||||
animation: indeterminate2 4s infinite linear;
|
||||
}
|
||||
}
|
||||
|
||||
&[md-mode=buffer] {
|
||||
.md-container {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.md-dashed:before {
|
||||
content: "";
|
||||
display: block;
|
||||
height: $progress-linear-bar-height;
|
||||
width: 100%;
|
||||
margin-top: 0px;
|
||||
position: absolute;
|
||||
background-color: transparent;
|
||||
background-size: 10px 10px !important;
|
||||
background-position: 0px -23px;
|
||||
animation: buffer 3s infinite linear;
|
||||
}
|
||||
}
|
||||
|
||||
&[md-mode=query] {
|
||||
.md-bar2 {
|
||||
animation: query .8s infinite cubic-bezier(0.390, 0.575, 0.565, 1.000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes indeterminate1 {
|
||||
0% {
|
||||
transform: translateX(-25%) scale(.5, 1);
|
||||
}
|
||||
10% {
|
||||
transform: translateX(25%) scale(.5, 1);
|
||||
}
|
||||
19.99% {
|
||||
transform: translateX(50%) scale(0, 1);
|
||||
}
|
||||
20% {
|
||||
transform: translateX(-37.5%) scale(.25, 1);
|
||||
}
|
||||
30% {
|
||||
transform: translateX(37.5%) scale(.25, 1);
|
||||
}
|
||||
34.99% {
|
||||
transform: translateX(50%) scale(0, 1);
|
||||
}
|
||||
36.99% {
|
||||
transform: translateX(50%) scale(0, 1);
|
||||
}
|
||||
37% {
|
||||
transform: translateX(-37.5%) scale(.25, 1);
|
||||
}
|
||||
47% {
|
||||
transform: translateX(20%) scale(.25, 1);
|
||||
}
|
||||
52% {
|
||||
transform: translateX(35%) scale(.05, 1);
|
||||
}
|
||||
55% {
|
||||
transform: translateX(35%) scale(.1, 1);
|
||||
}
|
||||
58% {
|
||||
transform: translateX(50%) scale(.1, 1);
|
||||
}
|
||||
61.99% {
|
||||
transform: translateX(50%) scale(0, 1);
|
||||
}
|
||||
69.99% {
|
||||
transform: translateX(50%) scale(0, 1);
|
||||
}
|
||||
70% {
|
||||
transform: translateX(-37.5%) scale(.25, 1);
|
||||
}
|
||||
80% {
|
||||
transform: translateX(20%) scale(.25, 1);
|
||||
}
|
||||
85% {
|
||||
transform: translateX(35%) scale(.05, 1);
|
||||
}
|
||||
88% {
|
||||
transform: translateX(35%) scale(.1, 1);
|
||||
}
|
||||
91% {
|
||||
transform: translateX(50%) scale(.1, 1);
|
||||
}
|
||||
92.99% {
|
||||
transform: translateX(50%) scale(0, 1);
|
||||
}
|
||||
93% {
|
||||
transform: translateX(-50%) scale(0, 1);
|
||||
}
|
||||
100% {
|
||||
transform: translateX(-25%) scale(.5, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes indeterminate2 {
|
||||
0% {
|
||||
transform: translateX(-50%) scale(0, 1);
|
||||
}
|
||||
25.99%{
|
||||
transform: translateX(-50%) scale(0, 1);
|
||||
}
|
||||
28% {
|
||||
transform: translateX(-37.5%) scale(.25, 1);
|
||||
}
|
||||
38% {
|
||||
transform: translateX(37.5%) scale(.25, 1);
|
||||
}
|
||||
42.99% {
|
||||
transform: translateX(50%) scale(0, 1);
|
||||
}
|
||||
46.99% {
|
||||
transform: translateX(50%) scale(0, 1);
|
||||
}
|
||||
49.99% {
|
||||
transform: translateX(50%) scale(0, 1);
|
||||
}
|
||||
50% {
|
||||
transform: translateX(-50%) scale(0, 1);
|
||||
}
|
||||
60% {
|
||||
transform: translateX(-25%) scale(.5, 1);
|
||||
}
|
||||
70% {
|
||||
transform: translateX(25%) scale(.5, 1);
|
||||
}
|
||||
79.99% {
|
||||
transform: translateX(50%) scale(0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes query {
|
||||
0% {
|
||||
opacity: 1;
|
||||
transform: translateX(35%) scale(.3, 1);
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: translateX(-50%) scale(0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes buffer {
|
||||
0% {
|
||||
opacity: 1;
|
||||
background-position: 0px -23px;
|
||||
}
|
||||
50% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
background-position: -200px -23px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
describe('mdProgressLinear', function() {
|
||||
|
||||
beforeEach(module('material.components.progressLinear'));
|
||||
|
||||
it('should set transform based on value', inject(function($compile, $rootScope, $mdConstant) {
|
||||
var element = $compile('<div>' +
|
||||
'<md-progress-linear value="{{progress}}">' +
|
||||
'</md-progress-linear>' +
|
||||
'</div>')($rootScope);
|
||||
|
||||
$rootScope.$apply(function() {
|
||||
$rootScope.progress = 50;
|
||||
});
|
||||
|
||||
var progress = element.find('md-progress-linear'),
|
||||
bar2 = angular.element(progress[0].querySelectorAll('.md-bar2'))[0];
|
||||
|
||||
expect(bar2.style[$mdConstant.CSS.TRANSFORM]).toEqual('translateX(-25%) scale(0.5, 1)');
|
||||
}));
|
||||
|
||||
it('should update aria-valuenow', inject(function($compile, $rootScope) {
|
||||
var element = $compile('<div>' +
|
||||
'<md-progress-linear value="{{progress}}">' +
|
||||
'</md-progress-linear>' +
|
||||
'</div>')($rootScope);
|
||||
|
||||
$rootScope.$apply(function() {
|
||||
$rootScope.progress = 50;
|
||||
});
|
||||
|
||||
var progress = element.find('md-progress-linear');
|
||||
|
||||
expect(progress.eq(0).attr('aria-valuenow')).toEqual('50');
|
||||
}));
|
||||
|
||||
it('should set transform based on buffer value', inject(function($compile, $rootScope, $mdConstant) {
|
||||
var element = $compile('<div>' +
|
||||
'<md-progress-linear value="{{progress}}" md-buffer-value="{{progress2}}">' +
|
||||
'</md-progress-linear>' +
|
||||
'</div>')($rootScope);
|
||||
|
||||
$rootScope.$apply(function() {
|
||||
$rootScope.progress = 50;
|
||||
$rootScope.progress2 = 75;
|
||||
});
|
||||
|
||||
var progress = element.find('md-progress-linear'),
|
||||
bar1 = angular.element(progress[0].querySelectorAll('.md-bar1'))[0];
|
||||
|
||||
expect(bar1.style[$mdConstant.CSS.TRANSFORM]).toEqual('translateX(-12.5%) scale(0.75, 1)');
|
||||
}));
|
||||
|
||||
it('should not set transform in query mode', inject(function($compile, $rootScope, $mdConstant) {
|
||||
var element = $compile('<div>' +
|
||||
'<md-progress-linear md-mode="query" value="{{progress}}">' +
|
||||
'</md-progress-linear>' +
|
||||
'</div>')($rootScope);
|
||||
|
||||
$rootScope.$apply(function() {
|
||||
$rootScope.progress = 80;
|
||||
});
|
||||
|
||||
var progress = element.find('md-progress-linear'),
|
||||
bar2 = angular.element(progress[0].querySelectorAll('.md-bar2'))[0];
|
||||
|
||||
expect(bar2.style[$mdConstant.CSS.TRANSFORM]).toBeFalsy();
|
||||
}));
|
||||
});
|
||||
@@ -0,0 +1,33 @@
|
||||
|
||||
<form ng-submit="submit()" ng-controller="AppCtrl" >
|
||||
<p>Selected Value: <span class="radioValue">{{ data.group1 }}</span> </p>
|
||||
|
||||
<md-radio-group ng-model="data.group1">
|
||||
|
||||
<md-radio-button value="Apple" aria-label="Label 1">Apple</md-radio-button>
|
||||
<md-radio-button value="Banana"> Banana </md-radio-button>
|
||||
<md-radio-button value="Mango" aria-label="Label 3">Mango</md-radio-button>
|
||||
|
||||
</md-radio-group>
|
||||
|
||||
<hr />
|
||||
|
||||
<p>Selected Value: <span class="radioValue">{{ data.group2 }}</span></p>
|
||||
|
||||
<md-radio-group ng-model="data.group2">
|
||||
|
||||
<md-radio-button ng-repeat="d in radioData"
|
||||
ng-value="d.value"
|
||||
ng-disabled=" d.isDisabled "
|
||||
aria-label="{{ d.label }}">
|
||||
{{ d.label }}
|
||||
</md-radio-button>
|
||||
|
||||
</md-radio-group>
|
||||
|
||||
<p>
|
||||
<md-button ng-click="addItem()">Add</md-button>
|
||||
<md-button ng-click="removeItem()">Remove</md-button>
|
||||
</p>
|
||||
|
||||
</form>
|
||||
@@ -0,0 +1,31 @@
|
||||
|
||||
angular.module('radioDemo1', ['ngMaterial'])
|
||||
|
||||
.controller('AppCtrl', function($scope) {
|
||||
|
||||
$scope.data = {
|
||||
group1 : 'Banana',
|
||||
group2 : '2'
|
||||
};
|
||||
|
||||
$scope.radioData = [
|
||||
{ label: '1', value: 1 },
|
||||
{ label: '2', value: 2 },
|
||||
{ label: '3', value: '3', isDisabled: true },
|
||||
{ label: '4', value: '4' }
|
||||
];
|
||||
|
||||
$scope.submit = function() {
|
||||
alert('submit');
|
||||
};
|
||||
|
||||
$scope.addItem = function() {
|
||||
var r = Math.ceil(Math.random() * 1000);
|
||||
$scope.radioData.push({ label: r, value: r });
|
||||
};
|
||||
|
||||
$scope.removeItem = function() {
|
||||
$scope.radioData.pop();
|
||||
};
|
||||
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
|
||||
body {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
hr {
|
||||
margin-left:-20px; opacity:0.3;
|
||||
}
|
||||
|
||||
md-radio-group {
|
||||
width:150px;
|
||||
}
|
||||
|
||||
p:last-child {
|
||||
padding-bottom: 50px;
|
||||
}
|
||||
|
||||
|
||||
[ng-controller] {
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.radioValue {
|
||||
margin-left: 5px;
|
||||
color: #0f9d58;
|
||||
font-weight: bold;
|
||||
padding:5px;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
|
||||
md-radio-button.md-THEME_NAME-theme {
|
||||
.md-off {
|
||||
border-color: '{{foreground-2}}';
|
||||
}
|
||||
|
||||
.md-on {
|
||||
background-color: '{{accent-color-0.87}}';
|
||||
}
|
||||
&.md-checked .md-off {
|
||||
border-color: '{{accent-color-0.87}}';
|
||||
}
|
||||
&.md-checked .md-ink-ripple {
|
||||
color: '{{accent-color-0.87}}';
|
||||
}
|
||||
.md-container .md-ripple {
|
||||
color: '{{accent-600}}';
|
||||
}
|
||||
|
||||
&:not([disabled]) {
|
||||
|
||||
&.md-warn {
|
||||
.md-on {
|
||||
background-color: '{{warn-color-0.87}}';
|
||||
}
|
||||
&.md-checked .md-off {
|
||||
border-color: '{{warn-color-0.87}}';
|
||||
}
|
||||
&.md-checked .md-ink-ripple {
|
||||
color: '{{warn-color-0.87}}';
|
||||
}
|
||||
.md-container .md-ripple {
|
||||
color: '{{warn-600}}';
|
||||
}
|
||||
}
|
||||
|
||||
&.md-primary {
|
||||
.md-on {
|
||||
background-color: '{{primary-color-0.87}}';
|
||||
}
|
||||
&.md-checked .md-off {
|
||||
border-color: '{{primary-color-0.87}}';
|
||||
}
|
||||
&.md-checked .md-ink-ripple {
|
||||
color: '{{primary-color-0.87}}';
|
||||
}
|
||||
.md-container .md-ripple {
|
||||
color: '{{primary-600}}';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&[disabled] {
|
||||
.md-container .md-off {
|
||||
border-color: '{{foreground-3}}';
|
||||
}
|
||||
.md-container .md-on {
|
||||
border-color: '{{foreground-3}}';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
md-radio-group.md-THEME_NAME-theme:focus:not(:empty) {
|
||||
border-color: '{{foreground-1}}';
|
||||
}
|
||||
80
UI/WebServerResources/scss/vendors/angular-material/components/radioButton/radio-button.scss
vendored
Normal file
80
UI/WebServerResources/scss/vendors/angular-material/components/radioButton/radio-button.scss
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
$radio-width: 16px !default;
|
||||
$radio-height: $radio-width !default;
|
||||
|
||||
md-radio-button,
|
||||
.md-switch-thumb { // Used in switch
|
||||
display: block;
|
||||
margin: 15px;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
|
||||
input {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.md-container {
|
||||
position: relative;
|
||||
top: 4px;
|
||||
display: inline-block;
|
||||
width: $radio-width;
|
||||
height: $radio-width;
|
||||
cursor: pointer;
|
||||
|
||||
.md-ripple-container {
|
||||
position: absolute;
|
||||
display: block;
|
||||
width: $radio-width * 3;
|
||||
height: $radio-width * 3;
|
||||
left: -$radio-width;
|
||||
top: -$radio-width;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.md-off {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
width: $radio-width;
|
||||
height: $radio-width;
|
||||
border: solid 2px;
|
||||
border-radius: 50%;
|
||||
transition: border-color ease 0.28s;
|
||||
}
|
||||
|
||||
.md-on {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: $radio-width;
|
||||
height: $radio-width;
|
||||
border-radius: 50%;
|
||||
transition: transform ease 0.28s;
|
||||
transform: scale(0);
|
||||
}
|
||||
|
||||
&.md-checked .md-on {
|
||||
transform: scale(0.55);
|
||||
}
|
||||
|
||||
.md-label {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
vertical-align: middle;
|
||||
white-space: normal;
|
||||
pointer-events: none;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.circle {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
}
|
||||
md-radio-group {
|
||||
border: 1px dotted transparent;
|
||||
display: block;
|
||||
outline: none;
|
||||
}
|
||||
288
UI/WebServerResources/scss/vendors/angular-material/components/radioButton/radioButton.js
vendored
Normal file
288
UI/WebServerResources/scss/vendors/angular-material/components/radioButton/radioButton.js
vendored
Normal file
@@ -0,0 +1,288 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
|
||||
/**
|
||||
* @ngdoc module
|
||||
* @name material.components.radioButton
|
||||
* @description radioButton module!
|
||||
*/
|
||||
angular.module('material.components.radioButton', [
|
||||
'material.core'
|
||||
])
|
||||
.directive('mdRadioGroup', mdRadioGroupDirective)
|
||||
.directive('mdRadioButton', mdRadioButtonDirective);
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @module material.components.radioButton
|
||||
* @name mdRadioGroup
|
||||
*
|
||||
* @restrict E
|
||||
*
|
||||
* @description
|
||||
* The `<md-radio-group>` directive identifies a grouping
|
||||
* container for the 1..n grouped radio buttons; specified using nested
|
||||
* `<md-radio-button>` tags.
|
||||
*
|
||||
* Note: `<md-radio-group>` and `<md-radio-button>` handle tabindex differently
|
||||
* than the native `<input type='radio'>` controls. Whereas the native controls
|
||||
* force the user to tab through all the radio buttons, `<md-radio-group>`
|
||||
* is focusable, and by default the `<md-radio-button>`s are not.
|
||||
*
|
||||
* @param {string} ng-model Assignable angular expression to data-bind to.
|
||||
* @param {boolean=} md-no-ink Use of attribute indicates flag to disable ink ripple effects.
|
||||
*
|
||||
* @usage
|
||||
* <hljs lang="html">
|
||||
* <md-radio-group ng-model="selected">
|
||||
*
|
||||
* <md-radio-button
|
||||
* ng-repeat="d in colorOptions"
|
||||
* ng-value="d.value" aria-label="{{ d.label }}">
|
||||
*
|
||||
* {{ d.label }}
|
||||
*
|
||||
* </md-radio-button>
|
||||
*
|
||||
* </md-radio-group>
|
||||
* </hljs>
|
||||
*
|
||||
*/
|
||||
function mdRadioGroupDirective($mdUtil, $mdConstant, $mdTheming) {
|
||||
RadioGroupController.prototype = createRadioGroupControllerProto();
|
||||
|
||||
return {
|
||||
restrict: 'E',
|
||||
controller: ['$element', RadioGroupController],
|
||||
require: ['mdRadioGroup', '?ngModel'],
|
||||
link: linkRadioGroup
|
||||
};
|
||||
|
||||
function linkRadioGroup(scope, element, attr, ctrls) {
|
||||
$mdTheming(element);
|
||||
var rgCtrl = ctrls[0];
|
||||
var ngModelCtrl = ctrls[1] || $mdUtil.fakeNgModel();
|
||||
|
||||
function keydownListener(ev) {
|
||||
switch(ev.keyCode) {
|
||||
case $mdConstant.KEY_CODE.LEFT_ARROW:
|
||||
case $mdConstant.KEY_CODE.UP_ARROW:
|
||||
ev.preventDefault();
|
||||
rgCtrl.selectPrevious();
|
||||
break;
|
||||
|
||||
case $mdConstant.KEY_CODE.RIGHT_ARROW:
|
||||
case $mdConstant.KEY_CODE.DOWN_ARROW:
|
||||
ev.preventDefault();
|
||||
rgCtrl.selectNext();
|
||||
break;
|
||||
|
||||
case $mdConstant.KEY_CODE.ENTER:
|
||||
var form = angular.element($mdUtil.getClosest(element[0], 'form'));
|
||||
if (form.length > 0) {
|
||||
form.triggerHandler('submit');
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rgCtrl.init(ngModelCtrl);
|
||||
|
||||
element.attr({
|
||||
'role': 'radiogroup',
|
||||
'tabIndex': element.attr('tabindex') || '0'
|
||||
})
|
||||
.on('keydown', keydownListener);
|
||||
|
||||
}
|
||||
|
||||
function RadioGroupController($element) {
|
||||
this._radioButtonRenderFns = [];
|
||||
this.$element = $element;
|
||||
}
|
||||
|
||||
function createRadioGroupControllerProto() {
|
||||
return {
|
||||
init: function(ngModelCtrl) {
|
||||
this._ngModelCtrl = ngModelCtrl;
|
||||
this._ngModelCtrl.$render = angular.bind(this, this.render);
|
||||
},
|
||||
add: function(rbRender) {
|
||||
this._radioButtonRenderFns.push(rbRender);
|
||||
},
|
||||
remove: function(rbRender) {
|
||||
var index = this._radioButtonRenderFns.indexOf(rbRender);
|
||||
if (index !== -1) {
|
||||
this._radioButtonRenderFns.splice(index, 1);
|
||||
}
|
||||
},
|
||||
render: function() {
|
||||
this._radioButtonRenderFns.forEach(function(rbRender) {
|
||||
rbRender();
|
||||
});
|
||||
},
|
||||
setViewValue: function(value, eventType) {
|
||||
this._ngModelCtrl.$setViewValue(value, eventType);
|
||||
// update the other radio buttons as well
|
||||
this.render();
|
||||
},
|
||||
getViewValue: function() {
|
||||
return this._ngModelCtrl.$viewValue;
|
||||
},
|
||||
selectNext: function() {
|
||||
return changeSelectedButton(this.$element, 1);
|
||||
},
|
||||
selectPrevious : function() {
|
||||
return changeSelectedButton(this.$element, -1);
|
||||
},
|
||||
setActiveDescendant: function (radioId) {
|
||||
this.$element.attr('aria-activedescendant', radioId);
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Change the radio group's selected button by a given increment.
|
||||
* If no button is selected, select the first button.
|
||||
*/
|
||||
function changeSelectedButton(parent, increment) {
|
||||
// Coerce all child radio buttons into an array, then wrap then in an iterator
|
||||
var buttons = $mdUtil.iterator(
|
||||
Array.prototype.slice.call(parent[0].querySelectorAll('md-radio-button')),
|
||||
true
|
||||
);
|
||||
|
||||
if (buttons.count()) {
|
||||
var validate = function (button) {
|
||||
// If disabled, then NOT valid
|
||||
return !angular.element(button).attr("disabled");
|
||||
};
|
||||
var selected = parent[0].querySelector('md-radio-button.md-checked');
|
||||
var target = buttons[increment < 0 ? 'previous' : 'next'](selected, validate) || buttons.first();
|
||||
// Activate radioButton's click listener (triggerHandler won't create a real click event)
|
||||
angular.element(target).triggerHandler('click');
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @module material.components.radioButton
|
||||
* @name mdRadioButton
|
||||
*
|
||||
* @restrict E
|
||||
*
|
||||
* @description
|
||||
* The `<md-radio-button>`directive is the child directive required to be used within `<md-radio-group>` elements.
|
||||
*
|
||||
* While similar to the `<input type="radio" ng-model="" value="">` directive,
|
||||
* the `<md-radio-button>` directive provides ink effects, ARIA support, and
|
||||
* supports use within named radio groups.
|
||||
*
|
||||
* @param {string} ngModel Assignable angular expression to data-bind to.
|
||||
* @param {string=} ngChange Angular expression to be executed when input changes due to user
|
||||
* interaction with the input element.
|
||||
* @param {string} ngValue Angular expression which sets the value to which the expression should
|
||||
* be set when selected.*
|
||||
* @param {string} value The value to which the expression should be set when selected.
|
||||
* @param {string=} name Property name of the form under which the control is published.
|
||||
* @param {string=} ariaLabel Adds label to radio button for accessibility.
|
||||
* Defaults to radio button's text. If no default text is found, a warning will be logged.
|
||||
*
|
||||
* @usage
|
||||
* <hljs lang="html">
|
||||
*
|
||||
* <md-radio-button value="1" aria-label="Label 1">
|
||||
* Label 1
|
||||
* </md-radio-button>
|
||||
*
|
||||
* <md-radio-button ng-model="color" ng-value="specialValue" aria-label="Green">
|
||||
* Green
|
||||
* </md-radio-button>
|
||||
*
|
||||
* </hljs>
|
||||
*
|
||||
*/
|
||||
function mdRadioButtonDirective($mdAria, $mdUtil, $mdTheming) {
|
||||
|
||||
var CHECKED_CSS = 'md-checked';
|
||||
|
||||
return {
|
||||
restrict: 'E',
|
||||
require: '^mdRadioGroup',
|
||||
transclude: true,
|
||||
template: '<div class="md-container" md-ink-ripple md-ink-ripple-checkbox>' +
|
||||
'<div class="md-off"></div>' +
|
||||
'<div class="md-on"></div>' +
|
||||
'</div>' +
|
||||
'<div ng-transclude class="md-label"></div>',
|
||||
link: link
|
||||
};
|
||||
|
||||
function link(scope, element, attr, rgCtrl) {
|
||||
var lastChecked;
|
||||
|
||||
$mdTheming(element);
|
||||
configureAria(element, scope);
|
||||
|
||||
rgCtrl.add(render);
|
||||
attr.$observe('value', render);
|
||||
|
||||
element
|
||||
.on('click', listener)
|
||||
.on('$destroy', function() {
|
||||
rgCtrl.remove(render);
|
||||
});
|
||||
|
||||
function listener(ev) {
|
||||
if (element[0].hasAttribute('disabled')) return;
|
||||
|
||||
scope.$apply(function() {
|
||||
rgCtrl.setViewValue(attr.value, ev && ev.type);
|
||||
});
|
||||
}
|
||||
|
||||
function render() {
|
||||
var checked = (rgCtrl.getViewValue() == attr.value);
|
||||
if (checked === lastChecked) {
|
||||
return;
|
||||
}
|
||||
lastChecked = checked;
|
||||
element.attr('aria-checked', checked);
|
||||
if (checked) {
|
||||
element.addClass(CHECKED_CSS);
|
||||
rgCtrl.setActiveDescendant(element.attr('id'));
|
||||
} else {
|
||||
element.removeClass(CHECKED_CSS);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Inject ARIA-specific attributes appropriate for each radio button
|
||||
*/
|
||||
function configureAria( element, scope ){
|
||||
scope.ariaId = buildAriaID();
|
||||
|
||||
element.attr({
|
||||
'id' : scope.ariaId,
|
||||
'role' : 'radio',
|
||||
'aria-checked' : 'false'
|
||||
});
|
||||
|
||||
$mdAria.expectWithText(element, 'aria-label');
|
||||
|
||||
/**
|
||||
* Build a unique ID for each radio button that will be used with aria-activedescendant.
|
||||
* Preserve existing ID if already specified.
|
||||
* @returns {*|string}
|
||||
*/
|
||||
function buildAriaID() {
|
||||
return attr.id || ( 'radio' + "_" + $mdUtil.nextUid() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
||||
258
UI/WebServerResources/scss/vendors/angular-material/components/radioButton/radioButton.spec.js
vendored
Normal file
258
UI/WebServerResources/scss/vendors/angular-material/components/radioButton/radioButton.spec.js
vendored
Normal file
@@ -0,0 +1,258 @@
|
||||
describe('radioButton', function() {
|
||||
var CHECKED_CSS = 'md-checked';
|
||||
|
||||
beforeEach(TestUtil.mockRaf);
|
||||
beforeEach(module('material.components.radioButton'));
|
||||
|
||||
it('should set checked css class', inject(function($compile, $rootScope) {
|
||||
var element = $compile('<md-radio-group ng-model="color">' +
|
||||
'<md-radio-button value="blue"></md-radio-button>' +
|
||||
'<md-radio-button value="green"></md-radio-button>' +
|
||||
'</md-radio-group>')($rootScope);
|
||||
|
||||
$rootScope.$apply(function(){
|
||||
$rootScope.color = 'green';
|
||||
});
|
||||
|
||||
var rbElements = element.find('md-radio-button');
|
||||
|
||||
expect(rbElements.eq(0).hasClass(CHECKED_CSS)).toEqual(false);
|
||||
expect(rbElements.eq(1).hasClass(CHECKED_CSS)).toEqual(true);
|
||||
}));
|
||||
|
||||
it('should support mixed values', inject(function($compile, $rootScope) {
|
||||
var element = $compile('<md-radio-group ng-model="value">' +
|
||||
'<md-radio-button value="1"></md-radio-button>' +
|
||||
'<md-radio-button value="2"></md-radio-button>' +
|
||||
'</md-radio-group>')($rootScope);
|
||||
|
||||
$rootScope.$apply(function(){
|
||||
$rootScope.value = 1;
|
||||
});
|
||||
|
||||
var rbElements = element.find('md-radio-button');
|
||||
expect(rbElements.eq(0).hasClass(CHECKED_CSS)).toEqual(true);
|
||||
}));
|
||||
|
||||
it('should set roles', inject(function($compile, $rootScope) {
|
||||
|
||||
var element = $compile('<md-radio-group ng-model="color">' +
|
||||
'<md-radio-button value="blue"></md-radio-button>' +
|
||||
'<md-radio-button value="green"></md-radio-button>' +
|
||||
'</md-radio-group>')($rootScope);
|
||||
|
||||
var rbGroupElement = element;
|
||||
expect(rbGroupElement.eq(0).attr('role')).toEqual('radiogroup');
|
||||
expect(rbGroupElement.find('md-radio-button').eq(0).attr('role')).toEqual('radio');
|
||||
}));
|
||||
|
||||
it('should set aria states', inject(function($compile, $rootScope) {
|
||||
var element = $compile('<md-radio-group ng-model="color">' +
|
||||
'<md-radio-button value="blue"></md-radio-button>' +
|
||||
'<md-radio-button value="green"></md-radio-button>' +
|
||||
'</md-radio-group>')($rootScope);
|
||||
|
||||
$rootScope.$apply(function(){
|
||||
$rootScope.color = 'green';
|
||||
});
|
||||
|
||||
var rbElements = element.find('md-radio-button');
|
||||
|
||||
expect(rbElements.eq(0).attr('aria-checked')).toEqual('false');
|
||||
expect(rbElements.eq(1).attr('aria-checked')).toEqual('true');
|
||||
|
||||
expect(element.attr('aria-activedescendant')).toEqual(rbElements.eq(1).attr('id'));
|
||||
expect(element.attr('aria-activedescendant')).not.toEqual(rbElements.eq(0).attr('id'));
|
||||
}));
|
||||
|
||||
it('should warn developers they need a label', inject(function($compile, $rootScope, $log){
|
||||
spyOn($log, "warn");
|
||||
var element = $compile('<md-radio-group ng-model="color">' +
|
||||
'<md-radio-button value="blue"></md-radio-button>' +
|
||||
'<md-radio-button value="green"></md-radio-button>' +
|
||||
'</md-radio-group>')($rootScope);
|
||||
|
||||
expect($log.warn).toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
it('should create an aria label from provided text', inject(function($compile, $rootScope) {
|
||||
var element = $compile('<md-radio-group ng-model="color">' +
|
||||
'<md-radio-button value="blue">Blue</md-radio-button>' +
|
||||
'<md-radio-button value="green">Green</md-radio-button>' +
|
||||
'</md-radio-group>')($rootScope);
|
||||
|
||||
var rbElements = element.find('md-radio-button');
|
||||
expect(rbElements.eq(0).attr('aria-label')).toEqual('Blue');
|
||||
}));
|
||||
|
||||
it('should preserve tabindex', inject(function($compile, $rootScope, $mdConstant) {
|
||||
var element = $compile('<md-radio-group ng-model="color" tabindex="3">' +
|
||||
'<md-radio-button value="blue"></md-radio-button>' +
|
||||
'<md-radio-button value="green"></md-radio-button>' +
|
||||
'</md-radio-group>')($rootScope);
|
||||
|
||||
var rbGroupElement = element.eq(0);
|
||||
expect(rbGroupElement.attr('tabindex')).toEqual('3');
|
||||
}));
|
||||
|
||||
it('should be operable via arrow keys', inject(function($compile, $rootScope, $mdConstant) {
|
||||
var element = $compile('<md-radio-group ng-model="color">' +
|
||||
'<md-radio-button value="blue"></md-radio-button>' +
|
||||
'<md-radio-button value="green"></md-radio-button>' +
|
||||
'</md-radio-group>')($rootScope);
|
||||
$rootScope.$apply(function(){
|
||||
$rootScope.color = 'blue';
|
||||
});
|
||||
|
||||
var rbGroupElement = element.eq(0);
|
||||
rbGroupElement.triggerHandler({
|
||||
type: 'keydown',
|
||||
keyCode: $mdConstant.KEY_CODE.RIGHT_ARROW
|
||||
});
|
||||
|
||||
expect($rootScope.color).toEqual('green');
|
||||
}));
|
||||
|
||||
describe('ng core radio button tests', function() {
|
||||
|
||||
it('should noop with no model', inject(function($compile, $rootScope) {
|
||||
var el;
|
||||
expect(function() {
|
||||
el = $compile('<md-radio-group>' +
|
||||
'<md-radio-button value="white">' +
|
||||
'</md-radio-group>')($rootScope);
|
||||
}).not.toThrow();
|
||||
var rbElements = el.find('md-radio-button');
|
||||
|
||||
// Fire off the render function with no ngModel, make sure nothing
|
||||
// goes unexpectedly.
|
||||
expect(function() {
|
||||
rbElements.eq(0).triggerHandler('click');
|
||||
}).not.toThrow();
|
||||
}));
|
||||
|
||||
it('should update the model', inject(function($compile, $rootScope) {
|
||||
var element = $compile('<md-radio-group ng-model="color">' +
|
||||
'<md-radio-button value="white"></md-radio-button>' +
|
||||
'<md-radio-button value="red"></md-radio-button>' +
|
||||
'<md-radio-button value="blue"></md-radio-button>' +
|
||||
'</md-radio-group>')($rootScope);
|
||||
var rbElements = element.find('md-radio-button');
|
||||
|
||||
$rootScope.$apply("color = 'white'");
|
||||
expect(rbElements.eq(0).hasClass(CHECKED_CSS)).toBe(true);
|
||||
expect(rbElements.eq(1).hasClass(CHECKED_CSS)).toBe(false);
|
||||
expect(rbElements.eq(2).hasClass(CHECKED_CSS)).toBe(false);
|
||||
|
||||
$rootScope.$apply("color = 'red'");
|
||||
expect(rbElements.eq(0).hasClass(CHECKED_CSS)).toBe(false);
|
||||
expect(rbElements.eq(1).hasClass(CHECKED_CSS)).toBe(true);
|
||||
expect(rbElements.eq(2).hasClass(CHECKED_CSS)).toBe(false);
|
||||
|
||||
rbElements.eq(2).triggerHandler('click');
|
||||
|
||||
expect($rootScope.color).toBe('blue');
|
||||
}));
|
||||
|
||||
it('should trigger a submit', inject(function($compile, $rootScope, $mdConstant) {
|
||||
|
||||
$rootScope.testValue = false;
|
||||
$rootScope.submitFn = function(){
|
||||
$rootScope.testValue = true;
|
||||
};
|
||||
var element = $compile('<div><form ng-submit="submitFn()">' +
|
||||
'<md-radio-group ng-model="color">' +
|
||||
'<md-radio-button value="white"></md-radio-button>' +
|
||||
'</md-radio-group>' +
|
||||
'</form></div>')($rootScope);
|
||||
|
||||
var formElement = element.find('form'),
|
||||
rbGroupElement = element.find('md-radio-group');
|
||||
|
||||
rbGroupElement.triggerHandler({
|
||||
type: 'keydown',
|
||||
keyCode: $mdConstant.KEY_CODE.ENTER
|
||||
});
|
||||
|
||||
expect($rootScope.testValue).toBe(true);
|
||||
}));
|
||||
|
||||
it('should be disabled', inject(function($compile, $rootScope) {
|
||||
var element = $compile('<md-radio-group ng-model="color">' +
|
||||
'<md-radio-button value="white" ng-disabled="isDisabled"></md-radio-button>' +
|
||||
'</md-radio-group>')($rootScope);
|
||||
var radio = element.find('md-radio-button');
|
||||
|
||||
$rootScope.$apply('isDisabled = true');
|
||||
$rootScope.$apply('color = null');
|
||||
radio.triggerHandler('click');
|
||||
expect($rootScope.color).toBe(null);
|
||||
|
||||
$rootScope.$apply('isDisabled = false');
|
||||
radio.triggerHandler('click');
|
||||
expect($rootScope.color).toBe('white');
|
||||
}));
|
||||
|
||||
it('should skip disabled on arrow key', inject(function($compile, $rootScope, $mdConstant) {
|
||||
var element = $compile(
|
||||
'<md-radio-group ng-model="color">' +
|
||||
' <md-radio-button value="red" ></md-radio-button>' +
|
||||
' <md-radio-button value="white" ng-disabled="isDisabled"></md-radio-button>' +
|
||||
' <md-radio-button value="blue" ></md-radio-button>' +
|
||||
'</md-radio-group>'
|
||||
)($rootScope);
|
||||
var rbGroupElement = element.eq(0);
|
||||
|
||||
$rootScope.$apply('isDisabled = true');
|
||||
$rootScope.$apply('color = "red"');
|
||||
expect($rootScope.color).toBe("red");
|
||||
|
||||
|
||||
rightArrow(); expect($rootScope.color).toEqual('blue');
|
||||
rightArrow(); expect($rootScope.color).toEqual('red');
|
||||
rightArrow(); expect($rootScope.color).toEqual('blue');
|
||||
|
||||
|
||||
$rootScope.$apply('isDisabled = false');
|
||||
|
||||
rightArrow();
|
||||
rightArrow(); expect($rootScope.color).toEqual('white');
|
||||
rightArrow(); expect($rootScope.color).toEqual('blue');
|
||||
|
||||
function rightArrow() {
|
||||
rbGroupElement.triggerHandler({
|
||||
type: 'keydown',
|
||||
keyCode: $mdConstant.KEY_CODE.RIGHT_ARROW
|
||||
});
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
it('should allow {{expr}} as value', inject(function($compile, $rootScope) {
|
||||
$rootScope.some = 11;
|
||||
var element = $compile('<md-radio-group ng-model="value">' +
|
||||
'<md-radio-button value="{{some}}"></md-radio-button>' +
|
||||
'<md-radio-button value="{{other}}"></<md-radio-button>' +
|
||||
'</md-radio-group>')($rootScope);
|
||||
var rbElements = element.find('md-radio-button');
|
||||
|
||||
$rootScope.$apply(function() {
|
||||
$rootScope.value = 'blue';
|
||||
$rootScope.some = 'blue';
|
||||
$rootScope.other = 'red';
|
||||
});
|
||||
|
||||
expect(rbElements.eq(0).hasClass(CHECKED_CSS)).toBe(true);
|
||||
expect(rbElements.eq(1).hasClass(CHECKED_CSS)).toBe(false);
|
||||
|
||||
rbElements.eq(1).triggerHandler('click');
|
||||
expect($rootScope.value).toBe('red');
|
||||
|
||||
$rootScope.$apply("other = 'non-red'");
|
||||
|
||||
expect(rbElements.eq(0).hasClass(CHECKED_CSS)).toBe(false);
|
||||
expect(rbElements.eq(1).hasClass(CHECKED_CSS)).toBe(false);
|
||||
}));
|
||||
|
||||
});
|
||||
});
|
||||
62
UI/WebServerResources/scss/vendors/angular-material/components/sidenav/demoBasicUsage/index.html
vendored
Normal file
62
UI/WebServerResources/scss/vendors/angular-material/components/sidenav/demoBasicUsage/index.html
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
|
||||
<div ng-controller="AppCtrl" layout="column" layout-fill>
|
||||
|
||||
<section layout="row" flex>
|
||||
|
||||
<md-sidenav class="md-sidenav-left md-whiteframe-z2" md-component-id="left" md-is-locked-open="$media('gt-md')">
|
||||
|
||||
<md-toolbar class="md-theme-indigo">
|
||||
<h1 class="md-toolbar-tools">Sidenav Left</h1>
|
||||
</md-toolbar>
|
||||
<md-content class="md-padding" ng-controller="LeftCtrl">
|
||||
<md-button ng-click="close()" class="md-primary" hide-gt-md>
|
||||
Close Sidenav Left
|
||||
</md-button>
|
||||
<p hide-md show-gt-md>
|
||||
This sidenav is locked open on your device. To go back to the default behavior,
|
||||
narrow your display.
|
||||
</p>
|
||||
</md-content>
|
||||
|
||||
</md-sidenav>
|
||||
|
||||
<md-content flex class="md-padding">
|
||||
|
||||
<div layout="column" layout-fill layout-align="center center">
|
||||
<p>
|
||||
The left sidenav will 'lock open' on a medium (>=960px wide) device.
|
||||
</p>
|
||||
|
||||
<div>
|
||||
<md-button ng-click="toggleLeft()"
|
||||
class="md-primary" hide-gt-md>
|
||||
Toggle left
|
||||
</md-button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<md-button ng-click="toggleRight()"
|
||||
class="md-primary">
|
||||
Toggle right
|
||||
</md-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</md-content>
|
||||
|
||||
<md-sidenav class="md-sidenav-right md-whiteframe-z2" md-component-id="right">
|
||||
|
||||
<md-toolbar class="md-theme-light">
|
||||
<h1 class="md-toolbar-tools">Sidenav Right</h1>
|
||||
</md-toolbar>
|
||||
<md-content ng-controller="RightCtrl" class="md-padding">
|
||||
<md-button ng-click="close()" class="md-primary">
|
||||
Close Sidenav Right
|
||||
</md-button>
|
||||
</md-content>
|
||||
|
||||
</md-sidenav>
|
||||
|
||||
</section>
|
||||
|
||||
</div>
|
||||
36
UI/WebServerResources/scss/vendors/angular-material/components/sidenav/demoBasicUsage/script.js
vendored
Normal file
36
UI/WebServerResources/scss/vendors/angular-material/components/sidenav/demoBasicUsage/script.js
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
|
||||
angular.module('sidenavDemo1', ['ngMaterial'])
|
||||
|
||||
.controller('AppCtrl', function($scope, $timeout, $mdSidenav, $log) {
|
||||
$scope.toggleLeft = function() {
|
||||
$mdSidenav('left').toggle()
|
||||
.then(function(){
|
||||
$log.debug("toggle left is done");
|
||||
});
|
||||
};
|
||||
$scope.toggleRight = function() {
|
||||
$mdSidenav('right').toggle()
|
||||
.then(function(){
|
||||
$log.debug("toggle RIGHT is done");
|
||||
});
|
||||
};
|
||||
})
|
||||
|
||||
.controller('LeftCtrl', function($scope, $timeout, $mdSidenav, $log) {
|
||||
$scope.close = function() {
|
||||
$mdSidenav('left').close()
|
||||
.then(function(){
|
||||
$log.debug("close LEFT is done");
|
||||
});
|
||||
|
||||
};
|
||||
})
|
||||
|
||||
.controller('RightCtrl', function($scope, $timeout, $mdSidenav, $log) {
|
||||
$scope.close = function() {
|
||||
$mdSidenav('right').close()
|
||||
.then(function(){
|
||||
$log.debug("close RIGHT is done");
|
||||
});
|
||||
};
|
||||
});
|
||||
3
UI/WebServerResources/scss/vendors/angular-material/components/sidenav/sidenav-theme.scss
vendored
Normal file
3
UI/WebServerResources/scss/vendors/angular-material/components/sidenav/sidenav-theme.scss
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
md-sidenav.md-THEME_NAME-theme {
|
||||
background-color: '{{background-hue-3}}';
|
||||
}
|
||||
293
UI/WebServerResources/scss/vendors/angular-material/components/sidenav/sidenav.js
vendored
Normal file
293
UI/WebServerResources/scss/vendors/angular-material/components/sidenav/sidenav.js
vendored
Normal file
@@ -0,0 +1,293 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc module
|
||||
* @name material.components.sidenav
|
||||
*
|
||||
* @description
|
||||
* A Sidenav QP component.
|
||||
*/
|
||||
angular.module('material.components.sidenav', [
|
||||
'material.core',
|
||||
'material.components.backdrop'
|
||||
])
|
||||
.factory('$mdSidenav', SidenavService )
|
||||
.directive('mdSidenav', SidenavDirective)
|
||||
.controller('$mdSidenavController', SidenavController);
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @ngdoc service
|
||||
* @name $mdSidenav
|
||||
* @module material.components.sidenav
|
||||
*
|
||||
* @description
|
||||
* $mdSidenav makes it easy to interact with multiple sidenavs
|
||||
* in an app.
|
||||
*
|
||||
* @usage
|
||||
*
|
||||
* ```javascript
|
||||
* // Toggle the given sidenav
|
||||
* $mdSidenav(componentId).toggle();
|
||||
*
|
||||
* // Open the given sidenav
|
||||
* $mdSidenav(componentId).open();
|
||||
*
|
||||
* // Close the given sidenav
|
||||
* $mdSidenav(componentId).close();
|
||||
* ```
|
||||
*/
|
||||
function SidenavService($mdComponentRegistry, $q) {
|
||||
return function(handle) {
|
||||
var errorMsg = "SideNav '" + handle + "' is not available!";
|
||||
|
||||
// Lookup the controller instance for the specified sidNav instance
|
||||
var instance = $mdComponentRegistry.get(handle);
|
||||
if(!instance) {
|
||||
$mdComponentRegistry.notFoundError(handle);
|
||||
}
|
||||
|
||||
return {
|
||||
isOpen: function() {
|
||||
return instance && instance.isOpen();
|
||||
},
|
||||
toggle: function() {
|
||||
return instance ? instance.toggle() : $q.reject(errorMsg);
|
||||
},
|
||||
open: function() {
|
||||
return instance ? instance.open() : $q.reject(errorMsg);
|
||||
},
|
||||
close: function() {
|
||||
return instance ? instance.close() : $q.reject(errorMsg);
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name mdSidenav
|
||||
* @module material.components.sidenav
|
||||
* @restrict E
|
||||
*
|
||||
* @description
|
||||
*
|
||||
* A Sidenav component that can be opened and closed programatically.
|
||||
*
|
||||
* By default, upon opening it will slide out on top of the main content area.
|
||||
*
|
||||
* @usage
|
||||
* <hljs lang="html">
|
||||
* <div layout="row" ng-controller="MyController">
|
||||
* <md-sidenav md-component-id="left" class="md-sidenav-left">
|
||||
* Left Nav!
|
||||
* </md-sidenav>
|
||||
*
|
||||
* <md-content>
|
||||
* Center Content
|
||||
* <md-button ng-click="openLeftMenu()">
|
||||
* Open Left Menu
|
||||
* </md-button>
|
||||
* </md-content>
|
||||
*
|
||||
* <md-sidenav md-component-id="right"
|
||||
* md-is-locked-open="$media('min-width: 333px')"
|
||||
* class="md-sidenav-right">
|
||||
* Right Nav!
|
||||
* </md-sidenav>
|
||||
* </div>
|
||||
* </hljs>
|
||||
*
|
||||
* <hljs lang="js">
|
||||
* var app = angular.module('myApp', ['ngMaterial']);
|
||||
* app.controller('MyController', function($scope, $mdSidenav) {
|
||||
* $scope.openLeftMenu = function() {
|
||||
* $mdSidenav('left').toggle();
|
||||
* };
|
||||
* });
|
||||
* </hljs>
|
||||
*
|
||||
* @param {expression=} md-is-open A model bound to whether the sidenav is opened.
|
||||
* @param {string=} md-component-id componentId to use with $mdSidenav service.
|
||||
* @param {expression=} md-is-locked-open When this expression evalutes to true,
|
||||
* the sidenav 'locks open': it falls into the content's flow instead
|
||||
* of appearing over it. This overrides the `is-open` attribute.
|
||||
*
|
||||
* A $media() function is exposed to the is-locked-open attribute, which
|
||||
* can be given a media query or one of the `sm`, `gt-sm`, `md`, `gt-md`, `lg` or `gt-lg` presets.
|
||||
* Examples:
|
||||
*
|
||||
* - `<md-sidenav md-is-locked-open="shouldLockOpen"></md-sidenav>`
|
||||
* - `<md-sidenav md-is-locked-open="$media('min-width: 1000px')"></md-sidenav>`
|
||||
* - `<md-sidenav md-is-locked-open="$media('sm')"></md-sidenav>` (locks open on small screens)
|
||||
*/
|
||||
function SidenavDirective($timeout, $animate, $parse, $mdMedia, $mdConstant, $compile, $mdTheming, $q, $document) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
scope: {
|
||||
isOpen: '=?mdIsOpen'
|
||||
},
|
||||
controller: '$mdSidenavController',
|
||||
compile: function(element) {
|
||||
element.addClass('md-closed');
|
||||
element.attr('tabIndex', '-1');
|
||||
return postLink;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Directive Post Link function...
|
||||
*/
|
||||
function postLink(scope, element, attr, sidenavCtrl) {
|
||||
var triggeringElement = null;
|
||||
var promise = $q.when(true);
|
||||
|
||||
var isLockedOpenParsed = $parse(attr.mdIsLockedOpen);
|
||||
var isLocked = function() {
|
||||
return isLockedOpenParsed(scope.$parent, {
|
||||
$media: $mdMedia
|
||||
});
|
||||
};
|
||||
var backdrop = $compile(
|
||||
'<md-backdrop class="md-sidenav-backdrop md-opaque ng-enter">'
|
||||
)(scope);
|
||||
|
||||
element.on('$destroy', sidenavCtrl.destroy);
|
||||
$mdTheming.inherit(backdrop, element);
|
||||
|
||||
scope.$watch(isLocked, updateIsLocked);
|
||||
scope.$watch('isOpen', updateIsOpen);
|
||||
|
||||
|
||||
// Publish special accessor for the Controller instance
|
||||
sidenavCtrl.$toggleOpen = toggleOpen;
|
||||
|
||||
/**
|
||||
* Toggle the DOM classes to indicate `locked`
|
||||
* @param isLocked
|
||||
*/
|
||||
function updateIsLocked(isLocked, oldValue) {
|
||||
if (isLocked === oldValue) {
|
||||
element.toggleClass('md-locked-open', !!isLocked);
|
||||
} else {
|
||||
$animate[isLocked ? 'addClass' : 'removeClass'](element, 'md-locked-open');
|
||||
}
|
||||
backdrop.toggleClass('md-locked-open', !!isLocked);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the SideNav view and attach/detach listeners
|
||||
* @param isOpen
|
||||
*/
|
||||
function updateIsOpen(isOpen) {
|
||||
var parent = element.parent();
|
||||
|
||||
parent[isOpen ? 'on' : 'off']('keydown', onKeyDown);
|
||||
backdrop[isOpen ? 'on' : 'off']('click', close);
|
||||
|
||||
if ( isOpen ) {
|
||||
// Capture upon opening..
|
||||
triggeringElement = $document[0].activeElement;
|
||||
}
|
||||
|
||||
return promise = $q.all([
|
||||
$animate[isOpen ? 'enter' : 'leave'](backdrop, parent),
|
||||
$animate[isOpen ? 'removeClass' : 'addClass'](element, 'md-closed').then(function() {
|
||||
// If we opened, and haven't closed again before the animation finished
|
||||
if (scope.isOpen) {
|
||||
element.focus();
|
||||
}
|
||||
})
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the sideNav view and publish a promise to be resolved when
|
||||
* the view animation finishes.
|
||||
*
|
||||
* @param isOpen
|
||||
* @returns {*}
|
||||
*/
|
||||
function toggleOpen( isOpen ) {
|
||||
if (scope.isOpen == isOpen ) {
|
||||
|
||||
return $q.when(true);
|
||||
|
||||
} else {
|
||||
var deferred = $q.defer();
|
||||
|
||||
// Toggle value to force an async `updateIsOpen()` to run
|
||||
scope.isOpen = isOpen;
|
||||
|
||||
$timeout(function() {
|
||||
|
||||
// When the current `updateIsOpen()` animation finishes
|
||||
promise.then(function(result){
|
||||
|
||||
if ( !scope.isOpen ) {
|
||||
// reset focus to originating element (if available) upon close
|
||||
triggeringElement && triggeringElement.focus();
|
||||
triggeringElement = null;
|
||||
}
|
||||
|
||||
deferred.resolve(result);
|
||||
});
|
||||
|
||||
},0,false);
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Auto-close sideNav when the `escape` key is pressed.
|
||||
* @param evt
|
||||
*/
|
||||
function onKeyDown(ev) {
|
||||
var isEscape = (ev.keyCode === $mdConstant.KEY_CODE.ESCAPE);
|
||||
return isEscape ? close(ev) : $q.when(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* With backdrop `clicks` or `escape` key-press, immediately
|
||||
* apply the CSS close transition... Then notify the controller
|
||||
* to close() and perform its own actions.
|
||||
*/
|
||||
function close(ev) {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
|
||||
return sidenavCtrl.close();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @private
|
||||
* @ngdoc controller
|
||||
* @name SidenavController
|
||||
* @module material.components.sidenav
|
||||
*
|
||||
*/
|
||||
function SidenavController($scope, $element, $attrs, $mdComponentRegistry, $q) {
|
||||
|
||||
var self = this;
|
||||
|
||||
// Use Default internal method until overridden by directive postLink
|
||||
|
||||
self.$toggleOpen = function() { return $q.when($scope.isOpen); };
|
||||
self.isOpen = function() { return !!$scope.isOpen; };
|
||||
self.open = function() { return self.$toggleOpen( true ); };
|
||||
self.close = function() { return self.$toggleOpen( false ); };
|
||||
self.toggle = function() { return self.$toggleOpen( !$scope.isOpen ); };
|
||||
|
||||
self.destroy = $mdComponentRegistry.register(self, $attrs.mdComponentId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
})();
|
||||
93
UI/WebServerResources/scss/vendors/angular-material/components/sidenav/sidenav.scss
vendored
Normal file
93
UI/WebServerResources/scss/vendors/angular-material/components/sidenav/sidenav.scss
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
$sidenav-default-width: 304px !default;
|
||||
|
||||
md-sidenav {
|
||||
position: absolute;
|
||||
|
||||
width: $sidenav-default-width;
|
||||
min-width: $sidenav-default-width;
|
||||
bottom: 0;
|
||||
z-index: $z-index-sidenav;
|
||||
background-color: white;
|
||||
overflow: auto;
|
||||
flex-direction: column;
|
||||
|
||||
&.md-closed {
|
||||
display: none;
|
||||
}
|
||||
&.md-closed-add,
|
||||
&.md-closed-remove {
|
||||
display: flex;
|
||||
/* this is required as of 1.3x to properly
|
||||
apply all styling in a show/hide animation */
|
||||
transition: 0s all;
|
||||
}
|
||||
|
||||
&.md-closed-add.md-closed-add-active,
|
||||
&.md-closed-remove.md-closed-remove-active {
|
||||
transition: $swift-ease-out;
|
||||
}
|
||||
|
||||
&.md-locked-open-add,
|
||||
&.md-locked-open-remove {
|
||||
position: static;
|
||||
display: flex;
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
&.md-locked-open {
|
||||
width: $sidenav-default-width;
|
||||
min-width: $sidenav-default-width;
|
||||
}
|
||||
|
||||
&.md-locked-open,
|
||||
&.md-locked-open.md-closed,
|
||||
&.md-locked-open.md-closed.md-sidenav-left,
|
||||
&.md-locked-open.md-closed.md-sidenav-right,
|
||||
&.md-locked-open-remove.md-closed {
|
||||
position: static;
|
||||
display: flex;
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
&.md-locked-open-remove-active {
|
||||
transition: width $swift-ease-in-duration $swift-ease-in-timing-function,
|
||||
min-width $swift-ease-in-duration $swift-ease-in-timing-function;
|
||||
width: 0;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
&.md-closed.md-locked-open-add {
|
||||
width: 0;
|
||||
min-width: 0;
|
||||
transform: translate3d(0%, 0, 0);
|
||||
}
|
||||
|
||||
&.md-closed.md-locked-open-add-active {
|
||||
transition: width $swift-ease-in-duration $swift-ease-in-timing-function,
|
||||
min-width $swift-ease-in-duration $swift-ease-in-timing-function;
|
||||
width: $sidenav-default-width;
|
||||
min-width: $sidenav-default-width;
|
||||
transform: translate3d(0%, 0, 0);
|
||||
}
|
||||
|
||||
@extend .md-sidenav-left;
|
||||
}
|
||||
.md-sidenav-backdrop.md-locked-open {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.md-sidenav-left {
|
||||
left: 0;
|
||||
top: 0;
|
||||
transform: translate3d(0%, 0, 0);
|
||||
&.md-closed {
|
||||
transform: translate3d(-100%, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.md-sidenav-right {
|
||||
left: 100%;
|
||||
top: 0;
|
||||
transform: translate3d(-100%, 0, 0);
|
||||
&.md-closed {
|
||||
transform: translate3d(0%, 0, 0);
|
||||
}
|
||||
}
|
||||
239
UI/WebServerResources/scss/vendors/angular-material/components/sidenav/sidenav.spec.js
vendored
Normal file
239
UI/WebServerResources/scss/vendors/angular-material/components/sidenav/sidenav.spec.js
vendored
Normal file
@@ -0,0 +1,239 @@
|
||||
describe('mdSidenav', function() {
|
||||
beforeEach(module('material.components.sidenav', 'ngAnimateMock', function($provide) {
|
||||
$provide.value('$$rAF', function(cb) { cb(); });
|
||||
}));
|
||||
|
||||
function setup(attrs) {
|
||||
var el;
|
||||
inject(function($compile, $rootScope) {
|
||||
var parent = angular.element('<div>');
|
||||
el = angular.element('<md-sidenav ' + (attrs||'') + '>');
|
||||
parent.append(el);
|
||||
$compile(parent)($rootScope);
|
||||
$rootScope.$apply();
|
||||
});
|
||||
return el;
|
||||
}
|
||||
|
||||
describe('directive', function() {
|
||||
|
||||
it('should bind isOpen attribute', inject(function($rootScope, $animate) {
|
||||
var el = setup('md-is-open="show"');
|
||||
$rootScope.$apply('show = true');
|
||||
|
||||
$animate.triggerCallbacks();
|
||||
expect(el.hasClass('md-closed')).toBe(false);
|
||||
expect(el.parent().find('md-backdrop').length).toBe(1);
|
||||
|
||||
$rootScope.$apply('show = false');
|
||||
$animate.triggerCallbacks();
|
||||
expect(el.hasClass('md-closed')).toBe(true);
|
||||
expect(el.parent().find('md-backdrop').length).toBe(0);
|
||||
}));
|
||||
|
||||
it('should close on escape', inject(function($rootScope, $animate, $mdConstant, $timeout) {
|
||||
var el = setup('md-is-open="show"');
|
||||
$rootScope.$apply('show = true');
|
||||
|
||||
$animate.triggerCallbacks();
|
||||
el.parent().triggerHandler({
|
||||
type: 'keydown',
|
||||
keyCode: $mdConstant.KEY_CODE.ESCAPE
|
||||
});
|
||||
$timeout.flush();
|
||||
expect($rootScope.show).toBe(false);
|
||||
}));
|
||||
|
||||
it('should close on backdrop click', inject(function($rootScope, $animate, $timeout) {
|
||||
var el = setup('md-is-open="show"');
|
||||
$rootScope.$apply('show = true');
|
||||
|
||||
$animate.triggerCallbacks();
|
||||
el.parent().find('md-backdrop').triggerHandler('click');
|
||||
$timeout.flush();
|
||||
expect($rootScope.show).toBe(false);
|
||||
}));
|
||||
|
||||
it('should focus sidenav on open', inject(function($rootScope, $animate, $document) {
|
||||
TestUtil.mockElementFocus(this);
|
||||
var el = setup('md-is-open="show"');
|
||||
$rootScope.$apply('show = true');
|
||||
|
||||
$animate.triggerCallbacks();
|
||||
expect($document.activeElement).toBe(el[0]);
|
||||
}));
|
||||
|
||||
it('should lock open when is-locked-open is true', inject(function($rootScope, $animate, $document) {
|
||||
var el = setup('md-is-open="show" md-is-locked-open="lock"');
|
||||
expect(el.hasClass('md-locked-open')).toBe(false);
|
||||
$rootScope.$apply('lock = true');
|
||||
expect(el.hasClass('md-locked-open')).toBe(true);
|
||||
$rootScope.$apply('show = true');
|
||||
$animate.triggerCallbacks();
|
||||
expect(el.parent().find('md-backdrop').hasClass('md-locked-open')).toBe(true);
|
||||
}));
|
||||
|
||||
it('should expose $mdMedia service as $media local in is-locked-open attribute', function() {
|
||||
var mdMediaSpy = jasmine.createSpy('$mdMedia');
|
||||
module(function($provide) {
|
||||
$provide.value('$mdMedia', mdMediaSpy);
|
||||
});
|
||||
inject(function($rootScope, $animate, $document, $mdMedia) {
|
||||
var el = setup('md-is-locked-open="$media(123)"');
|
||||
expect($mdMedia).toHaveBeenCalledWith(123);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('controller', function() {
|
||||
it('should create controller', function() {
|
||||
var el = setup('');
|
||||
var controller = el.controller('mdSidenav');
|
||||
expect(controller).not.toBe(undefined);
|
||||
});
|
||||
|
||||
it('should open and close and toggle', inject(function($timeout) {
|
||||
var el = setup('');
|
||||
var scope = el.isolateScope();
|
||||
var controller = el.controller('mdSidenav');
|
||||
|
||||
// Should start closed
|
||||
expect(el.hasClass('md-closed')).toBe(true);
|
||||
|
||||
controller.open();
|
||||
scope.$apply();
|
||||
|
||||
expect(el.hasClass('md-closed')).toBe(false);
|
||||
|
||||
controller.close();
|
||||
scope.$apply();
|
||||
|
||||
expect(el.hasClass('md-closed')).toBe(true);
|
||||
|
||||
controller.toggle();
|
||||
scope.$apply();
|
||||
|
||||
expect(el.hasClass('md-closed')).toBe(false);
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
describe("controller Promise API", function() {
|
||||
var $animate, $rootScope;
|
||||
|
||||
function flush() {
|
||||
if ( !$rootScope.$$phase) {
|
||||
$rootScope.$apply();
|
||||
}
|
||||
$animate.triggerCallbacks();
|
||||
}
|
||||
|
||||
beforeEach( inject(function(_$animate_,_$rootScope_,_$timeout_) {
|
||||
$animate = _$animate_;
|
||||
$rootScope = _$rootScope_;
|
||||
$timeout = _$timeout_;
|
||||
}));
|
||||
|
||||
|
||||
it('should open(), close(), and toggle() with promises', function () {
|
||||
var el = setup('');
|
||||
var scope = el.isolateScope();
|
||||
var controller = el.controller('mdSidenav');
|
||||
|
||||
var openDone = 0, closeDone = 0, toggleDone = 0;
|
||||
var onOpen = function() { openDone++; };
|
||||
var onClose = function() { closeDone++; };
|
||||
var onToggle = function() { toggleDone++; };
|
||||
|
||||
controller
|
||||
.open()
|
||||
.then(onOpen)
|
||||
.then(controller.close)
|
||||
.then(onClose);
|
||||
|
||||
flush();
|
||||
expect(openDone).toBe(1);
|
||||
flush();
|
||||
expect(closeDone).toBe(1);
|
||||
|
||||
controller
|
||||
.close()
|
||||
.then(onClose);
|
||||
|
||||
flush();
|
||||
expect(closeDone).toBe(2);
|
||||
expect(scope.isOpen).toBe(false);
|
||||
|
||||
controller
|
||||
.toggle()
|
||||
.then(onToggle);
|
||||
|
||||
flush();
|
||||
expect(toggleDone).toBe(1);
|
||||
expect(scope.isOpen).toBe(true);
|
||||
});
|
||||
|
||||
|
||||
it('should open() to work multiple times before close()', function () {
|
||||
var el = setup('');
|
||||
var controller = el.controller('mdSidenav');
|
||||
|
||||
var openDone = 0, closeDone = 0;
|
||||
var onOpen = function() { openDone++; };
|
||||
var onClose = function() { closeDone++; };
|
||||
|
||||
controller
|
||||
.open()
|
||||
.then(onOpen)
|
||||
.then(controller.open)
|
||||
.then(onOpen);
|
||||
|
||||
flush();
|
||||
expect(openDone).toBe(2);
|
||||
expect(closeDone).toBe(0);
|
||||
expect(el.hasClass('md-closed')).toBe(false);
|
||||
|
||||
controller
|
||||
.close()
|
||||
.then(onClose);
|
||||
|
||||
flush();
|
||||
expect(openDone).toBe(2);
|
||||
expect(closeDone).toBe(1);
|
||||
expect(el.hasClass('md-closed')).toBe(true);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('$mdSidenav Service', function() {
|
||||
it('should grab instance', inject(function($mdSidenav) {
|
||||
var el = setup('md-component-id="left"');
|
||||
var scope = el.isolateScope();
|
||||
|
||||
var instance = $mdSidenav('left');
|
||||
expect(instance).toBeTruthy();
|
||||
|
||||
instance.open();
|
||||
scope.$apply();
|
||||
|
||||
expect(el.hasClass('md-closed')).toBe(false);
|
||||
|
||||
instance.close();
|
||||
scope.$apply();
|
||||
|
||||
expect(el.hasClass('md-closed')).toBe(true);
|
||||
|
||||
instance.toggle();
|
||||
scope.$apply();
|
||||
|
||||
expect(el.hasClass('md-closed')).toBe(false);
|
||||
|
||||
instance.toggle();
|
||||
scope.$apply();
|
||||
|
||||
expect(el.hasClass('md-closed')).toBe(true);
|
||||
}));
|
||||
});
|
||||
|
||||
});
|
||||
55
UI/WebServerResources/scss/vendors/angular-material/components/slider/demoBasicUsage/index.html
vendored
Normal file
55
UI/WebServerResources/scss/vendors/angular-material/components/slider/demoBasicUsage/index.html
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
|
||||
<div ng-controller="AppCtrl">
|
||||
<md-content class="md-padding">
|
||||
|
||||
<h3>
|
||||
RGB <span ng-attr-style="border: 1px solid #333; background: rgb({{color.red}},{{color.green}},{{color.blue}})"> </span>
|
||||
</h3>
|
||||
|
||||
<div layout>
|
||||
<div flex="10" layout layout-align="center center">
|
||||
<span>R</span>
|
||||
</div>
|
||||
<md-slider flex min="0" max="255" ng-model="color.red" aria-label="red" id="red-slider" class="md-warn">
|
||||
</md-slider>
|
||||
<div flex="20" layout layout-align="center center">
|
||||
<input type="number" ng-model="color.red" aria-label="red" aria-controls="red-slider">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div layout>
|
||||
<div flex="10" layout layout-align="center center">
|
||||
<span>G</span>
|
||||
</div>
|
||||
<md-slider flex ng-model="color.green" min="0" max="255" aria-label="green" id="green-slider" class="md-accent">
|
||||
</md-slider>
|
||||
<div flex="20" layout layout-align="center center">
|
||||
<input type="number" ng-model="color.green" aria-label="green" aria-controls="green-slider">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div layout>
|
||||
<div flex="10" layout layout-align="center center">
|
||||
<span>B</span>
|
||||
</div>
|
||||
<md-slider flex ng-model="color.blue" min="0" max="255" aria-label="blue" id="blue-slider">
|
||||
</md-slider>
|
||||
<div flex="20" layout layout-align="center center">
|
||||
<input type="number" ng-model="color.blue" aria-label="blue" aria-controls="blue-slider">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3>Rating: {{rating}}/5</h3>
|
||||
<md-slider md-discrete ng-model="rating" step="1" min="1" max="5" aria-label="rating">
|
||||
</md-slider>
|
||||
|
||||
<h3>Disabled</h3>
|
||||
<md-slider ng-model="disabled1" ng-disabled="true" aria-label="Disabled 1"></md-slider>
|
||||
<md-slider ng-model="disabled2" ng-disabled="true" aria-label="Disabled 2"></md-slider>
|
||||
|
||||
<h3>Disabled, Discrete</h3>
|
||||
<md-slider ng-model="disabled1" ng-disabled="true" step="3" md-discrete min="0" max="10" aria-label="Disabled discrete 1"></md-slider>
|
||||
<md-slider ng-model="disabled2" ng-disabled="true" step="10" md-discrete aria-label="Disabled discrete 2"></md-slider>
|
||||
|
||||
</md-content>
|
||||
</div>
|
||||
16
UI/WebServerResources/scss/vendors/angular-material/components/slider/demoBasicUsage/script.js
vendored
Normal file
16
UI/WebServerResources/scss/vendors/angular-material/components/slider/demoBasicUsage/script.js
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
angular.module('sliderDemo1', ['ngMaterial'])
|
||||
|
||||
.controller('AppCtrl', function($scope) {
|
||||
|
||||
$scope.color = {
|
||||
red: Math.floor(Math.random() * 255),
|
||||
green: Math.floor(Math.random() * 255),
|
||||
blue: Math.floor(Math.random() * 255)
|
||||
};
|
||||
|
||||
$scope.rating = 3;
|
||||
$scope.disabled1 = 0;
|
||||
$scope.disabled2 = 70;
|
||||
|
||||
});
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
input[type="number"] {
|
||||
text-align: center;
|
||||
}
|
||||
87
UI/WebServerResources/scss/vendors/angular-material/components/slider/slider-theme.scss
vendored
Normal file
87
UI/WebServerResources/scss/vendors/angular-material/components/slider/slider-theme.scss
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
md-slider.md-THEME_NAME-theme {
|
||||
|
||||
.md-track {
|
||||
background-color: '{{foreground-3}}';
|
||||
}
|
||||
.md-track-ticks {
|
||||
background-color: '{{foreground-4}}';
|
||||
}
|
||||
.md-focus-thumb {
|
||||
background-color: '{{foreground-2}}';
|
||||
}
|
||||
.md-focus-ring {
|
||||
border-color: '{{foreground-4}}';
|
||||
}
|
||||
.md-disabled-thumb {
|
||||
border-color: '{{background-hue-3}}';
|
||||
}
|
||||
&.md-min .md-thumb:after {
|
||||
background-color: '{{background-hue-3}}';
|
||||
}
|
||||
|
||||
.md-track.md-track-fill {
|
||||
background-color: '{{primary-color}}';
|
||||
}
|
||||
.md-thumb:after {
|
||||
border-color: '{{primary-color}}';
|
||||
background-color: '{{primary-color}}';
|
||||
}
|
||||
.md-sign {
|
||||
background-color: '{{primary-color}}';
|
||||
&:after {
|
||||
border-top-color: '{{primary-color}}';
|
||||
}
|
||||
}
|
||||
.md-thumb-text {
|
||||
color: '{{primary-contrast}}';
|
||||
}
|
||||
|
||||
&.md-warn {
|
||||
.md-track-fill {
|
||||
background-color: '{{warn-color}}';
|
||||
}
|
||||
.md-thumb:after {
|
||||
border-color: '{{warn-color}}';
|
||||
background-color: '{{warn-color}}';
|
||||
}
|
||||
.md-sign {
|
||||
background-color: '{{warn-color}}';
|
||||
|
||||
&:after {
|
||||
border-top-color: '{{warn-color}}';
|
||||
}
|
||||
}
|
||||
.md-thumb-text {
|
||||
color: '{{warn-contrast}}';
|
||||
}
|
||||
}
|
||||
|
||||
&.md-accent {
|
||||
.md-track-fill {
|
||||
background-color: '{{accent-color}}';
|
||||
}
|
||||
.md-thumb:after {
|
||||
border-color: '{{accent-color}}';
|
||||
background-color: '{{accent-color}}';
|
||||
}
|
||||
.md-sign {
|
||||
background-color: '{{accent-color}}';
|
||||
|
||||
&:after {
|
||||
border-top-color: '{{accent-color}}';
|
||||
}
|
||||
}
|
||||
.md-thumb-text {
|
||||
color: '{{accent-contrast}}';
|
||||
}
|
||||
}
|
||||
|
||||
&[disabled] {
|
||||
.md-thumb:after {
|
||||
border-color: '{{foreground-3}}';
|
||||
}
|
||||
&:not(.md-min) .md-thumb:after {
|
||||
background-color: '{{foreground-3}}';
|
||||
}
|
||||
}
|
||||
}
|
||||
403
UI/WebServerResources/scss/vendors/angular-material/components/slider/slider.js
vendored
Normal file
403
UI/WebServerResources/scss/vendors/angular-material/components/slider/slider.js
vendored
Normal file
@@ -0,0 +1,403 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc module
|
||||
* @name material.components.slider
|
||||
*/
|
||||
angular.module('material.components.slider', [
|
||||
'material.core'
|
||||
])
|
||||
.directive('mdSlider', SliderDirective);
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name mdSlider
|
||||
* @module material.components.slider
|
||||
* @restrict E
|
||||
* @description
|
||||
* The `<md-slider>` component allows the user to choose from a range of
|
||||
* values.
|
||||
*
|
||||
* It has two modes: 'normal' mode, where the user slides between a wide range
|
||||
* of values, and 'discrete' mode, where the user slides between only a few
|
||||
* select values.
|
||||
*
|
||||
* To enable discrete mode, add the `md-discrete` attribute to a slider,
|
||||
* and use the `step` attribute to change the distance between
|
||||
* values the user is allowed to pick.
|
||||
*
|
||||
* @usage
|
||||
* <h4>Normal Mode</h4>
|
||||
* <hljs lang="html">
|
||||
* <md-slider ng-model="myValue" min="5" max="500">
|
||||
* </md-slider>
|
||||
* </hljs>
|
||||
* <h4>Discrete Mode</h4>
|
||||
* <hljs lang="html">
|
||||
* <md-slider md-discrete ng-model="myDiscreteValue" step="10" min="10" max="130">
|
||||
* </md-slider>
|
||||
* </hljs>
|
||||
*
|
||||
* @param {boolean=} md-discrete Whether to enable discrete mode.
|
||||
* @param {number=} step The distance between values the user is allowed to pick. Default 1.
|
||||
* @param {number=} min The minimum value the user is allowed to pick. Default 0.
|
||||
* @param {number=} max The maximum value the user is allowed to pick. Default 100.
|
||||
*/
|
||||
function SliderDirective($mdTheming) {
|
||||
return {
|
||||
scope: {},
|
||||
require: ['?ngModel', 'mdSlider'],
|
||||
controller: SliderController,
|
||||
template:
|
||||
'<div class="md-track-container">' +
|
||||
'<div class="md-track"></div>' +
|
||||
'<div class="md-track md-track-fill"></div>' +
|
||||
'<div class="md-track-ticks"></div>' +
|
||||
'</div>' +
|
||||
'<div class="md-thumb-container">' +
|
||||
'<div class="md-thumb"></div>' +
|
||||
'<div class="md-focus-thumb"></div>' +
|
||||
'<div class="md-focus-ring"></div>' +
|
||||
'<div class="md-sign">' +
|
||||
'<span class="md-thumb-text"></span>' +
|
||||
'</div>' +
|
||||
'<div class="md-disabled-thumb"></div>' +
|
||||
'</div>',
|
||||
link: postLink
|
||||
};
|
||||
|
||||
function postLink(scope, element, attr, ctrls) {
|
||||
$mdTheming(element);
|
||||
var ngModelCtrl = ctrls[0] || {
|
||||
// Mock ngModelController if it doesn't exist to give us
|
||||
// the minimum functionality needed
|
||||
$setViewValue: function(val) {
|
||||
this.$viewValue = val;
|
||||
this.$viewChangeListeners.forEach(function(cb) { cb(); });
|
||||
},
|
||||
$parsers: [],
|
||||
$formatters: [],
|
||||
$viewChangeListeners: []
|
||||
};
|
||||
|
||||
var sliderCtrl = ctrls[1];
|
||||
sliderCtrl.init(ngModelCtrl);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* We use a controller for all the logic so that we can expose a few
|
||||
* things to unit tests
|
||||
*/
|
||||
function SliderController($scope, $element, $attrs, $$rAF, $window, $mdAria, $mdUtil, $mdConstant) {
|
||||
|
||||
this.init = function init(ngModelCtrl) {
|
||||
var thumb = angular.element($element[0].querySelector('.md-thumb'));
|
||||
var thumbText = angular.element($element[0].querySelector('.md-thumb-text'));
|
||||
var thumbContainer = thumb.parent();
|
||||
var trackContainer = angular.element($element[0].querySelector('.md-track-container'));
|
||||
var activeTrack = angular.element($element[0].querySelector('.md-track-fill'));
|
||||
var tickContainer = angular.element($element[0].querySelector('.md-track-ticks'));
|
||||
var throttledRefreshDimensions = $mdUtil.throttle(refreshSliderDimensions, 5000);
|
||||
|
||||
// Default values, overridable by $attrss
|
||||
$attrs.min ? $attrs.$observe('min', updateMin) : updateMin(0);
|
||||
$attrs.max ? $attrs.$observe('max', updateMax) : updateMax(100);
|
||||
$attrs.step ? $attrs.$observe('step', updateStep) : updateStep(1);
|
||||
|
||||
// We have to manually stop the $watch on ngDisabled because it exists
|
||||
// on the parent $scope, and won't be automatically destroyed when
|
||||
// the component is destroyed.
|
||||
var stopDisabledWatch = angular.noop;
|
||||
if ($attrs.ngDisabled) {
|
||||
stopDisabledWatch = $scope.$parent.$watch($attrs.ngDisabled, updateAriaDisabled);
|
||||
}
|
||||
|
||||
$mdAria.expect($element, 'aria-label');
|
||||
|
||||
$element.attr('tabIndex', 0);
|
||||
$element.attr('role', 'slider');
|
||||
$element.on('keydown', keydownListener);
|
||||
|
||||
var hammertime = new Hammer($element[0], {
|
||||
recognizers: [
|
||||
[Hammer.Pan, { direction: Hammer.DIRECTION_HORIZONTAL }]
|
||||
]
|
||||
});
|
||||
hammertime.on('hammer.input', onInput);
|
||||
hammertime.on('panstart', onPanStart);
|
||||
hammertime.on('pan', onPan);
|
||||
hammertime.on('panend', onPanEnd);
|
||||
|
||||
// On resize, recalculate the slider's dimensions and re-render
|
||||
function updateAll() {
|
||||
refreshSliderDimensions();
|
||||
ngModelRender();
|
||||
redrawTicks();
|
||||
}
|
||||
setTimeout(updateAll);
|
||||
|
||||
var debouncedUpdateAll = $$rAF.debounce(updateAll);
|
||||
angular.element($window).on('resize', debouncedUpdateAll);
|
||||
|
||||
$scope.$on('$destroy', function() {
|
||||
angular.element($window).off('resize', debouncedUpdateAll);
|
||||
hammertime.destroy();
|
||||
stopDisabledWatch();
|
||||
});
|
||||
|
||||
ngModelCtrl.$render = ngModelRender;
|
||||
ngModelCtrl.$viewChangeListeners.push(ngModelRender);
|
||||
ngModelCtrl.$formatters.push(minMaxValidator);
|
||||
ngModelCtrl.$formatters.push(stepValidator);
|
||||
|
||||
/**
|
||||
* Attributes
|
||||
*/
|
||||
var min;
|
||||
var max;
|
||||
var step;
|
||||
function updateMin(value) {
|
||||
min = parseFloat(value);
|
||||
$element.attr('aria-valuemin', value);
|
||||
updateAll();
|
||||
}
|
||||
function updateMax(value) {
|
||||
max = parseFloat(value);
|
||||
$element.attr('aria-valuemax', value);
|
||||
updateAll();
|
||||
}
|
||||
function updateStep(value) {
|
||||
step = parseFloat(value);
|
||||
redrawTicks();
|
||||
}
|
||||
function updateAriaDisabled(isDisabled) {
|
||||
$element.attr('aria-disabled', !!isDisabled);
|
||||
}
|
||||
|
||||
// Draw the ticks with canvas.
|
||||
// The alternative to drawing ticks with canvas is to draw one $element for each tick,
|
||||
// which could quickly become a performance bottleneck.
|
||||
var tickCanvas, tickCtx;
|
||||
function redrawTicks() {
|
||||
if (!angular.isDefined($attrs.mdDiscrete)) return;
|
||||
|
||||
var numSteps = Math.floor( (max - min) / step );
|
||||
if (!tickCanvas) {
|
||||
var trackTicksStyle = $window.getComputedStyle(tickContainer[0]);
|
||||
tickCanvas = angular.element('<canvas style="position:absolute;">');
|
||||
tickCtx = tickCanvas[0].getContext('2d');
|
||||
tickCtx.fillStyle = trackTicksStyle.backgroundColor || 'black';
|
||||
tickContainer.append(tickCanvas);
|
||||
}
|
||||
var dimensions = getSliderDimensions();
|
||||
tickCanvas[0].width = dimensions.width;
|
||||
tickCanvas[0].height = dimensions.height;
|
||||
|
||||
var distance;
|
||||
for (var i = 0; i <= numSteps; i++) {
|
||||
distance = Math.floor(dimensions.width * (i / numSteps));
|
||||
tickCtx.fillRect(distance - 1, 0, 2, dimensions.height);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Refreshing Dimensions
|
||||
*/
|
||||
var sliderDimensions = {};
|
||||
refreshSliderDimensions();
|
||||
function refreshSliderDimensions() {
|
||||
sliderDimensions = trackContainer[0].getBoundingClientRect();
|
||||
}
|
||||
function getSliderDimensions() {
|
||||
throttledRefreshDimensions();
|
||||
return sliderDimensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* left/right arrow listener
|
||||
*/
|
||||
function keydownListener(ev) {
|
||||
if($element[0].hasAttribute('disabled')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var changeAmount;
|
||||
if (ev.keyCode === $mdConstant.KEY_CODE.LEFT_ARROW) {
|
||||
changeAmount = -step;
|
||||
} else if (ev.keyCode === $mdConstant.KEY_CODE.RIGHT_ARROW) {
|
||||
changeAmount = step;
|
||||
}
|
||||
if (changeAmount) {
|
||||
if (ev.metaKey || ev.ctrlKey || ev.altKey) {
|
||||
changeAmount *= 4;
|
||||
}
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
$scope.$evalAsync(function() {
|
||||
setModelValue(ngModelCtrl.$viewValue + changeAmount);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ngModel setters and validators
|
||||
*/
|
||||
function setModelValue(value) {
|
||||
ngModelCtrl.$setViewValue( minMaxValidator(stepValidator(value)) );
|
||||
}
|
||||
function ngModelRender() {
|
||||
|
||||
if (isNaN(ngModelCtrl.$viewValue)) {
|
||||
ngModelCtrl.$viewValue = ngModelCtrl.$modelValue;
|
||||
}
|
||||
|
||||
var percent = (ngModelCtrl.$viewValue - min) / (max - min);
|
||||
$scope.modelValue = ngModelCtrl.$viewValue;
|
||||
$element.attr('aria-valuenow', ngModelCtrl.$viewValue);
|
||||
setSliderPercent(percent);
|
||||
thumbText.text( ngModelCtrl.$viewValue );
|
||||
}
|
||||
|
||||
function minMaxValidator(value) {
|
||||
if (angular.isNumber(value)) {
|
||||
return Math.max(min, Math.min(max, value));
|
||||
}
|
||||
}
|
||||
function stepValidator(value) {
|
||||
if (angular.isNumber(value)) {
|
||||
return Math.round(value / step) * step;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param percent 0-1
|
||||
*/
|
||||
function setSliderPercent(percent) {
|
||||
activeTrack.css('width', (percent * 100) + '%');
|
||||
thumbContainer.css(
|
||||
$mdConstant.CSS.TRANSFORM,
|
||||
'translate3d(' + getSliderDimensions().width * percent + 'px,0,0)'
|
||||
);
|
||||
$element.toggleClass('md-min', percent === 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Slide listeners
|
||||
*/
|
||||
var isSliding = false;
|
||||
var isDiscrete = angular.isDefined($attrs.mdDiscrete);
|
||||
|
||||
function onInput(ev) {
|
||||
if (!isSliding && ev.eventType === Hammer.INPUT_START &&
|
||||
!$element[0].hasAttribute('disabled')) {
|
||||
|
||||
isSliding = true;
|
||||
|
||||
$element.addClass('active');
|
||||
$element[0].focus();
|
||||
refreshSliderDimensions();
|
||||
|
||||
onPan(ev);
|
||||
|
||||
ev.srcEvent.stopPropagation();
|
||||
|
||||
} else if (isSliding && ev.eventType === Hammer.INPUT_END) {
|
||||
|
||||
if ( isSliding && isDiscrete ) onPanEnd(ev);
|
||||
isSliding = false;
|
||||
|
||||
$element.removeClass('panning active');
|
||||
}
|
||||
}
|
||||
function onPanStart() {
|
||||
if (!isSliding) return;
|
||||
$element.addClass('panning');
|
||||
}
|
||||
function onPan(ev) {
|
||||
if (!isSliding) return;
|
||||
|
||||
// While panning discrete, update only the
|
||||
// visual positioning but not the model value.
|
||||
|
||||
if ( isDiscrete ) adjustThumbPosition( ev.center.x );
|
||||
else doSlide( ev.center.x );
|
||||
|
||||
ev.preventDefault();
|
||||
ev.srcEvent.stopPropagation();
|
||||
}
|
||||
|
||||
function onPanEnd(ev) {
|
||||
if ( isDiscrete && !$element[0].hasAttribute('disabled') ) {
|
||||
// Convert exact to closest discrete value.
|
||||
// Slide animate the thumb... and then update the model value.
|
||||
|
||||
var exactVal = percentToValue( positionToPercent( ev.center.x ));
|
||||
var closestVal = minMaxValidator( stepValidator(exactVal) );
|
||||
|
||||
setSliderPercent( valueToPercent(closestVal));
|
||||
$$rAF(function(){
|
||||
setModelValue( closestVal );
|
||||
});
|
||||
|
||||
ev.preventDefault();
|
||||
ev.srcEvent.stopPropagation();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Expose for testing
|
||||
*/
|
||||
this._onInput = onInput;
|
||||
this._onPanStart = onPanStart;
|
||||
this._onPan = onPan;
|
||||
|
||||
/**
|
||||
* Slide the UI by changing the model value
|
||||
* @param x
|
||||
*/
|
||||
function doSlide( x ) {
|
||||
$scope.$evalAsync( function() {
|
||||
setModelValue( percentToValue( positionToPercent(x) ));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Slide the UI without changing the model (while dragging/panning)
|
||||
* @param x
|
||||
*/
|
||||
function adjustThumbPosition( x ) {
|
||||
var exactVal = percentToValue( positionToPercent( x ));
|
||||
var closestVal = minMaxValidator( stepValidator(exactVal) );
|
||||
setSliderPercent( positionToPercent(x) );
|
||||
thumbText.text( closestVal );
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert horizontal position on slider to percentage value of offset from beginning...
|
||||
* @param x
|
||||
* @returns {number}
|
||||
*/
|
||||
function positionToPercent( x ) {
|
||||
return Math.max(0, Math.min(1, (x - sliderDimensions.left) / (sliderDimensions.width)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert percentage offset on slide to equivalent model value
|
||||
* @param percent
|
||||
* @returns {*}
|
||||
*/
|
||||
function percentToValue( percent ) {
|
||||
return (min + percent * (max - min));
|
||||
}
|
||||
|
||||
function valueToPercent( val ) {
|
||||
return (val - min)/(max - min);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
})();
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user