Component.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. Ext.define('Ext.theme.material.Component', {
  2. override: 'Ext.Component',
  3. config: {
  4. /**
  5. * @cfg {Boolean/Object/String} ripple
  6. * Set to truthy, Color or Object value for the ripple.
  7. * @cfg {String} ripple.color The background color of the ripple.
  8. * @cfg {Array} ripple.position Position for the ripple to start at [x,y].
  9. * Determines if a Ripple effect should happen whenever this element is pressed.
  10. *
  11. * For example:
  12. * {
  13. * ripple: true
  14. * }
  15. *
  16. * Or:
  17. *
  18. * {
  19. * ripple: {
  20. * color: 'red'
  21. * }
  22. * }
  23. *
  24. * For complex components, individual elements can suppress ripples by adding the
  25. * `x-no-ripple` class to disable rippling for a tree of elements.
  26. *
  27. * @since 7.0.0
  28. */
  29. ripple: null,
  30. labelAlign: 'top'
  31. },
  32. initComponent: function() {
  33. var me = this;
  34. me.callParent();
  35. if (me.ripple) {
  36. me.on('afterrender', function() {
  37. me.updateRipple(me.getRipple());
  38. }, me);
  39. }
  40. },
  41. updateRipple: function(ripple) {
  42. var me = this,
  43. el = me.el;
  44. if (Ext.isIE9m) {
  45. Ext.log({ level: 'warn' }, 'Ripple effect is not supported in IE9 and below!');
  46. return;
  47. }
  48. if (el) {
  49. el.un('touchstart', 'onRippleStart', me);
  50. el.un('touchend', 'onRippleStart', me);
  51. el.destroyAllRipples();
  52. el.on(ripple.release ? 'touchend' : 'touchstart', 'onRippleStart', me);
  53. }
  54. },
  55. shouldRipple: function(e) {
  56. var me = this,
  57. disabled = me.getDisabled && me.getDisabled(),
  58. el = me.el,
  59. ripple = !disabled && me.getRipple(),
  60. target;
  61. if (ripple && e) {
  62. target = e.getTarget(me.noRippleSelector);
  63. if (target) {
  64. if ((el.dom === target) || el.contains(target)) {
  65. ripple = null;
  66. }
  67. }
  68. }
  69. return ripple;
  70. },
  71. onRippleStart: function(e) {
  72. var me = this,
  73. ripple = this.shouldRipple(e);
  74. if (e.button === 0 && ripple) {
  75. me.el.ripple(e, ripple);
  76. }
  77. },
  78. privates: {
  79. noRippleSelector: '.' + Ext.baseCSSPrefix + 'no-ripple',
  80. /**
  81. * Queue a function to run when the component is visible & painted. If those conditions
  82. * are met, the function will execute immediately, otherwise it will wait until it is
  83. * visible and painted.
  84. *
  85. * @param {String} fn The function to execute on this component.
  86. * @param {Object[]} [args] The arguments to pass.
  87. * @return {Boolean} `true` if the function was executed immediately.
  88. *
  89. * @private
  90. */
  91. whenVisible: function(fn, args) {
  92. var me = this,
  93. listener, pending, visible;
  94. args = args || Ext.emptyArray;
  95. listener = me.visibleListener;
  96. pending = me.pendingVisible;
  97. visible = me.isVisible(true);
  98. if (!visible && !listener) {
  99. me.visibleListener = Ext.on({
  100. scope: me,
  101. show: 'handleGlobalShow',
  102. destroyable: true
  103. });
  104. }
  105. if (visible) {
  106. // Due to animations, it's possible that we may get called
  107. // and the show event hasn't fired. If that is the case
  108. // then just run now
  109. if (pending) {
  110. pending[fn] = args;
  111. me.runWhenVisible();
  112. }
  113. else {
  114. me[fn].apply(me, args);
  115. }
  116. }
  117. else {
  118. if (!pending) {
  119. me.pendingVisible = pending = {};
  120. }
  121. pending[fn] = args;
  122. }
  123. return visible;
  124. },
  125. clearWhenVisible: function(fn) {
  126. var me = this,
  127. pending = me.pendingVisible;
  128. if (pending) {
  129. delete pending[fn];
  130. if (Ext.Object.isEmpty(pending)) {
  131. me.pendingVisible = null;
  132. me.visibleListener = Ext.destroy(me.visibleListener);
  133. }
  134. }
  135. },
  136. runWhenVisible: function() {
  137. var me = this,
  138. pending = me.pendingVisible,
  139. key;
  140. me.pendingVisible = null;
  141. me.visibleListener = Ext.destroy(me.visibleListener);
  142. for (key in pending) {
  143. me[key].apply(me, pending[key]);
  144. }
  145. },
  146. handleGlobalShow: function(c) {
  147. var me = this;
  148. if (me.isVisible(true) && (c === me || me.isDescendantOf(c))) {
  149. me.runWhenVisible();
  150. }
  151. }
  152. }
  153. }, function() {
  154. Ext.namespace('Ext.theme.is').Material = true;
  155. Ext.theme.name = 'Material';
  156. });