mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-10-07 12:57:14 +00:00
Restructure Sass files and folders for proper application Sass development
This commit is contained in:
1 parent
a87bbc2de5
commit
5217c0ac64
207 files changed
+54
-285
No files matched your search
@@ -0,0 +1,244 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
angular.module('material.components.tabs')
|
||||
.directive('mdTab', MdTabDirective);
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name mdTab
|
||||
* @module material.components.tabs
|
||||
*
|
||||
* @restrict E
|
||||
*
|
||||
* @description
|
||||
* `<md-tab>` is the nested directive used [within `<md-tabs>`] to specify each tab with a **label** and optional *view content*.
|
||||
*
|
||||
* If the `label` attribute is not specified, then an optional `<md-tab-label>` tag can be used to specify more
|
||||
* complex tab header markup. If neither the **label** nor the **md-tab-label** are specified, then the nested
|
||||
* markup of the `<md-tab>` is used as the tab header markup.
|
||||
*
|
||||
* If a tab **label** has been identified, then any **non-**`<md-tab-label>` markup
|
||||
* will be considered tab content and will be transcluded to the internal `<div class="md-tabs-content">` container.
|
||||
*
|
||||
* This container is used by the TabsController to show/hide the active tab's content view. This synchronization is
|
||||
* automatically managed by the internal TabsController whenever the tab selection changes. Selection changes can
|
||||
* be initiated via data binding changes, programmatic invocation, or user gestures.
|
||||
*
|
||||
* @param {string=} label Optional attribute to specify a simple string as the tab label
|
||||
* @param {boolean=} md-active When evaluteing to true, selects the tab.
|
||||
* @param {boolean=} disabled If present, disabled tab selection.
|
||||
* @param {expression=} md-on-deselect Expression to be evaluated after the tab has been de-selected.
|
||||
* @param {expression=} md-on-select Expression to be evaluated after the tab has been selected.
|
||||
*
|
||||
*
|
||||
* @usage
|
||||
*
|
||||
* <hljs lang="html">
|
||||
* <md-tab label="" disabled="" md-on-select="" md-on-deselect="" >
|
||||
* <h3>My Tab content</h3>
|
||||
* </md-tab>
|
||||
*
|
||||
* <md-tab >
|
||||
* <md-tab-label>
|
||||
* <h3>My Tab content</h3>
|
||||
* </md-tab-label>
|
||||
* <p>
|
||||
* Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium,
|
||||
* totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae
|
||||
* dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit,
|
||||
* sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.
|
||||
* </p>
|
||||
* </md-tab>
|
||||
* </hljs>
|
||||
*
|
||||
*/
|
||||
function MdTabDirective($mdInkRipple, $compile, $mdUtil, $mdConstant, $timeout) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
require: ['mdTab', '^mdTabs'],
|
||||
controller: '$mdTab',
|
||||
scope: {
|
||||
onSelect: '&mdOnSelect',
|
||||
onDeselect: '&mdOnDeselect',
|
||||
label: '@'
|
||||
},
|
||||
compile: compile
|
||||
};
|
||||
|
||||
function compile(element, attr) {
|
||||
var tabLabel = element.find('md-tab-label');
|
||||
|
||||
if (tabLabel.length) {
|
||||
// If a tab label element is found, remove it for later re-use.
|
||||
tabLabel.remove();
|
||||
|
||||
} else if (angular.isDefined(attr.label)) {
|
||||
// Otherwise, try to use attr.label as the label
|
||||
tabLabel = angular.element('<md-tab-label>').html(attr.label);
|
||||
|
||||
} else {
|
||||
// If nothing is found, use the tab's content as the label
|
||||
tabLabel = angular.element('<md-tab-label>')
|
||||
.append(element.contents().remove());
|
||||
}
|
||||
|
||||
// Everything that's left as a child is the tab's content.
|
||||
var tabContent = element.contents().remove();
|
||||
|
||||
return function postLink(scope, element, attr, ctrls) {
|
||||
|
||||
var tabItemCtrl = ctrls[0]; // Controller for THIS tabItemCtrl
|
||||
var tabsCtrl = ctrls[1]; // Controller for ALL tabs
|
||||
|
||||
scope.$watch(
|
||||
function () { return attr.label; },
|
||||
function () { $timeout(function () { tabsCtrl.scope.$broadcast('$mdTabsChanged'); }, 0, false); }
|
||||
);
|
||||
|
||||
transcludeTabContent();
|
||||
configureAria();
|
||||
|
||||
var detachRippleFn = $mdInkRipple.attachTabBehavior(scope, element, {
|
||||
colorElement: tabsCtrl.inkBarElement
|
||||
});
|
||||
tabsCtrl.add(tabItemCtrl);
|
||||
scope.$on('$destroy', function() {
|
||||
detachRippleFn();
|
||||
tabsCtrl.remove(tabItemCtrl);
|
||||
});
|
||||
element.on('$destroy', function () {
|
||||
//-- wait for item to be removed from the dom
|
||||
$timeout(function () {
|
||||
tabsCtrl.scope.$broadcast('$mdTabsChanged');
|
||||
}, 0, false);
|
||||
});
|
||||
|
||||
if (!angular.isDefined(attr.ngClick)) {
|
||||
element.on('click', defaultClickListener);
|
||||
}
|
||||
element.on('keydown', keydownListener);
|
||||
scope.onSwipe = onSwipe;
|
||||
|
||||
if (angular.isNumber(scope.$parent.$index)) {
|
||||
watchNgRepeatIndex();
|
||||
}
|
||||
if (angular.isDefined(attr.mdActive)) {
|
||||
watchActiveAttribute();
|
||||
}
|
||||
watchDisabled();
|
||||
|
||||
function transcludeTabContent() {
|
||||
// Clone the label we found earlier, and $compile and append it
|
||||
var label = tabLabel.clone();
|
||||
element.append(label);
|
||||
$compile(label)(scope.$parent);
|
||||
|
||||
// Clone the content we found earlier, and mark it for later placement into
|
||||
// the proper content area.
|
||||
tabItemCtrl.content = tabContent.clone();
|
||||
}
|
||||
|
||||
//defaultClickListener isn't applied if the user provides an ngClick expression.
|
||||
function defaultClickListener() {
|
||||
scope.$apply(function() {
|
||||
tabsCtrl.select(tabItemCtrl);
|
||||
tabsCtrl.focus(tabItemCtrl);
|
||||
});
|
||||
}
|
||||
function keydownListener(ev) {
|
||||
if (ev.keyCode == $mdConstant.KEY_CODE.SPACE || ev.keyCode == $mdConstant.KEY_CODE.ENTER ) {
|
||||
// Fire the click handler to do normal selection if space is pressed
|
||||
element.triggerHandler('click');
|
||||
ev.preventDefault();
|
||||
} else if (ev.keyCode === $mdConstant.KEY_CODE.LEFT_ARROW) {
|
||||
scope.$evalAsync(function() {
|
||||
tabsCtrl.focus(tabsCtrl.previous(tabItemCtrl));
|
||||
});
|
||||
} else if (ev.keyCode === $mdConstant.KEY_CODE.RIGHT_ARROW) {
|
||||
scope.$evalAsync(function() {
|
||||
tabsCtrl.focus(tabsCtrl.next(tabItemCtrl));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function onSwipe(ev) {
|
||||
scope.$apply(function() {
|
||||
if (ev.type === 'swipeleft') {
|
||||
tabsCtrl.select(tabsCtrl.next());
|
||||
} else {
|
||||
tabsCtrl.select(tabsCtrl.previous());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// If tabItemCtrl is part of an ngRepeat, move the tabItemCtrl in our internal array
|
||||
// when its $index changes
|
||||
function watchNgRepeatIndex() {
|
||||
// The tabItemCtrl has an isolate scope, so we watch the $index on the parent.
|
||||
scope.$watch('$parent.$index', function $indexWatchAction(newIndex) {
|
||||
tabsCtrl.move(tabItemCtrl, newIndex);
|
||||
});
|
||||
}
|
||||
|
||||
function watchActiveAttribute() {
|
||||
var unwatch = scope.$parent.$watch('!!(' + attr.mdActive + ')', activeWatchAction);
|
||||
scope.$on('$destroy', unwatch);
|
||||
|
||||
function activeWatchAction(isActive) {
|
||||
var isSelected = tabsCtrl.getSelectedItem() === tabItemCtrl;
|
||||
|
||||
if (isActive && !isSelected) {
|
||||
tabsCtrl.select(tabItemCtrl);
|
||||
} else if (!isActive && isSelected) {
|
||||
tabsCtrl.deselect(tabItemCtrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function watchDisabled() {
|
||||
scope.$watch(tabItemCtrl.isDisabled, disabledWatchAction);
|
||||
|
||||
function disabledWatchAction(isDisabled) {
|
||||
element.attr('aria-disabled', isDisabled);
|
||||
|
||||
// Auto select `next` tab when disabled
|
||||
var isSelected = (tabsCtrl.getSelectedItem() === tabItemCtrl);
|
||||
if (isSelected && isDisabled) {
|
||||
tabsCtrl.select(tabsCtrl.next() || tabsCtrl.previous());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function configureAria() {
|
||||
// Link together the content area and tabItemCtrl with an id
|
||||
var tabId = attr.id || ('tab_' + $mdUtil.nextUid());
|
||||
|
||||
element.attr({
|
||||
id: tabId,
|
||||
role: 'tab',
|
||||
tabIndex: -1 //this is also set on select/deselect in tabItemCtrl
|
||||
});
|
||||
|
||||
// Only setup the contentContainer's aria attributes if tab content is provided
|
||||
if (tabContent.length) {
|
||||
var tabContentId = 'content_' + tabId;
|
||||
if (!element.attr('aria-controls')) {
|
||||
element.attr('aria-controls', tabContentId);
|
||||
}
|
||||
tabItemCtrl.contentContainer.attr({
|
||||
id: tabContentId,
|
||||
role: 'tabpanel',
|
||||
'aria-labelledby': tabId
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
})();
|
||||
Reference in new issue
Block a user