You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

131 lines
4.9 KiB

7 years ago
  1. /*!
  2. * Angular Material Design
  3. * https://github.com/angular/material
  4. * @license MIT
  5. * v1.1.3
  6. */
  7. goog.provide('ngmaterial.components.subheader');
  8. goog.require('ngmaterial.components.sticky');
  9. goog.require('ngmaterial.core');
  10. /**
  11. * @ngdoc module
  12. * @name material.components.subheader
  13. * @description
  14. * SubHeader module
  15. *
  16. * Subheaders are special list tiles that delineate distinct sections of a
  17. * list or grid list and are typically related to the current filtering or
  18. * sorting criteria. Subheader tiles are either displayed inline with tiles or
  19. * can be associated with content, for example, in an adjacent column.
  20. *
  21. * Upon scrolling, subheaders remain pinned to the top of the screen and remain
  22. * pinned until pushed on or off screen by the next subheader. @see [Material
  23. * Design Specifications](https://www.google.com/design/spec/components/subheaders.html)
  24. *
  25. * > To improve the visual grouping of content, use the system color for your subheaders.
  26. *
  27. */
  28. MdSubheaderDirective['$inject'] = ["$mdSticky", "$compile", "$mdTheming", "$mdUtil", "$mdAria"];
  29. angular
  30. .module('material.components.subheader', [
  31. 'material.core',
  32. 'material.components.sticky'
  33. ])
  34. .directive('mdSubheader', MdSubheaderDirective);
  35. /**
  36. * @ngdoc directive
  37. * @name mdSubheader
  38. * @module material.components.subheader
  39. *
  40. * @restrict E
  41. *
  42. * @description
  43. * The `md-subheader` directive creates a sticky subheader for a section.
  44. *
  45. * Developers are able to disable the stickiness of the subheader by using the following markup
  46. *
  47. * <hljs lang="html">
  48. * <md-subheader class="md-no-sticky">Not Sticky</md-subheader>
  49. * </hljs>
  50. *
  51. * ### Notes
  52. * - The `md-subheader` directive uses the <a ng-href="api/service/$mdSticky">$mdSticky</a> service
  53. * to make the subheader sticky.
  54. *
  55. * > Whenever the current browser doesn't support stickiness natively, the subheader
  56. * will be compiled twice to create a sticky clone of the subheader.
  57. *
  58. * @usage
  59. * <hljs lang="html">
  60. * <md-subheader>Online Friends</md-subheader>
  61. * </hljs>
  62. */
  63. function MdSubheaderDirective($mdSticky, $compile, $mdTheming, $mdUtil, $mdAria) {
  64. return {
  65. restrict: 'E',
  66. replace: true,
  67. transclude: true,
  68. template: (
  69. '<div class="md-subheader _md">' +
  70. ' <div class="md-subheader-inner">' +
  71. ' <div class="md-subheader-content"></div>' +
  72. ' </div>' +
  73. '</div>'
  74. ),
  75. link: function postLink(scope, element, attr, controllers, transclude) {
  76. $mdTheming(element);
  77. element.addClass('_md');
  78. // Remove the ngRepeat attribute from the root element, because we don't want to compile
  79. // the ngRepeat for the sticky clone again.
  80. $mdUtil.prefixer().removeAttribute(element, 'ng-repeat');
  81. var outerHTML = element[0].outerHTML;
  82. function getContent(el) {
  83. return angular.element(el[0].querySelector('.md-subheader-content'));
  84. }
  85. // Set the ARIA attributes on the original element since it keeps it's original place in
  86. // the DOM, whereas the clones are in reverse order. Should be done after the outerHTML,
  87. // in order to avoid having multiple element be marked as headers.
  88. attr.$set('role', 'heading');
  89. $mdAria.expect(element, 'aria-level', '2');
  90. // Transclude the user-given contents of the subheader
  91. // the conventional way.
  92. transclude(scope, function(clone) {
  93. getContent(element).append(clone);
  94. });
  95. // Create another clone, that uses the outer and inner contents
  96. // of the element, that will be 'stickied' as the user scrolls.
  97. if (!element.hasClass('md-no-sticky')) {
  98. transclude(scope, function(clone) {
  99. // If the user adds an ng-if or ng-repeat directly to the md-subheader element, the
  100. // compiled clone below will only be a comment tag (since they replace their elements with
  101. // a comment) which cannot be properly passed to the $mdSticky; so we wrap it in our own
  102. // DIV to ensure we have something $mdSticky can use
  103. var wrapper = $compile('<div class="md-subheader-wrapper" aria-hidden="true">' + outerHTML + '</div>')(scope);
  104. // Delay initialization until after any `ng-if`/`ng-repeat`/etc has finished before
  105. // attempting to create the clone
  106. $mdUtil.nextTick(function() {
  107. // Append our transcluded clone into the wrapper.
  108. // We don't have to recompile the element again, because the clone is already
  109. // compiled in it's transclusion scope. If we recompile the outerHTML of the new clone, we would lose
  110. // our ngIf's and other previous registered bindings / properties.
  111. getContent(wrapper).append(clone);
  112. });
  113. // Make the element sticky and provide the stickyClone our self, to avoid recompilation of the subheader
  114. // element.
  115. $mdSticky(scope, element, wrapper);
  116. });
  117. }
  118. }
  119. };
  120. }
  121. ngmaterial.components.subheader = angular.module("material.components.subheader");