Ohm-Management - Projektarbeit B-ME
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.

VMenu.js 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. import '../../../src/stylus/components/_menus.styl';
  2. import Vue from 'vue';
  3. // Mixins
  4. import Delayable from '../../mixins/delayable';
  5. import Dependent from '../../mixins/dependent';
  6. import Detachable from '../../mixins/detachable';
  7. import Menuable from '../../mixins/menuable.js';
  8. import Returnable from '../../mixins/returnable';
  9. import Toggleable from '../../mixins/toggleable';
  10. import Themeable from '../../mixins/themeable';
  11. // Component level mixins
  12. import Activator from './mixins/menu-activator';
  13. import Generators from './mixins/menu-generators';
  14. import Keyable from './mixins/menu-keyable';
  15. import Position from './mixins/menu-position';
  16. // Directives
  17. import ClickOutside from '../../directives/click-outside';
  18. import Resize from '../../directives/resize';
  19. // Helpers
  20. import { convertToUnit, getSlotType } from '../../util/helpers';
  21. import ThemeProvider from '../../util/ThemeProvider';
  22. import { consoleError } from '../../util/console';
  23. /* @vue/component */
  24. export default Vue.extend({
  25. name: 'v-menu',
  26. provide: function provide() {
  27. return {
  28. // Pass theme through to default slot
  29. theme: this.theme
  30. };
  31. },
  32. directives: {
  33. ClickOutside: ClickOutside,
  34. Resize: Resize
  35. },
  36. mixins: [Activator, Dependent, Delayable, Detachable, Generators, Keyable, Menuable, Position, Returnable, Toggleable, Themeable],
  37. props: {
  38. auto: Boolean,
  39. closeOnClick: {
  40. type: Boolean,
  41. default: true
  42. },
  43. closeOnContentClick: {
  44. type: Boolean,
  45. default: true
  46. },
  47. disabled: Boolean,
  48. fullWidth: Boolean,
  49. maxHeight: { default: 'auto' },
  50. openOnClick: {
  51. type: Boolean,
  52. default: true
  53. },
  54. offsetX: Boolean,
  55. offsetY: Boolean,
  56. openOnHover: Boolean,
  57. origin: {
  58. type: String,
  59. default: 'top left'
  60. },
  61. transition: {
  62. type: [Boolean, String],
  63. default: 'v-menu-transition'
  64. }
  65. },
  66. data: function data() {
  67. return {
  68. defaultOffset: 8,
  69. hasJustFocused: false,
  70. resizeTimeout: null
  71. };
  72. },
  73. computed: {
  74. calculatedLeft: function calculatedLeft() {
  75. var menuWidth = Math.max(this.dimensions.content.width, parseFloat(this.calculatedMinWidth));
  76. if (!this.auto) return this.calcLeft(menuWidth);
  77. return this.calcXOverflow(this.calcLeftAuto(), menuWidth) + 'px';
  78. },
  79. calculatedMaxHeight: function calculatedMaxHeight() {
  80. return this.auto ? '200px' : convertToUnit(this.maxHeight);
  81. },
  82. calculatedMaxWidth: function calculatedMaxWidth() {
  83. return isNaN(this.maxWidth) ? this.maxWidth : this.maxWidth + 'px';
  84. },
  85. calculatedMinWidth: function calculatedMinWidth() {
  86. if (this.minWidth) {
  87. return isNaN(this.minWidth) ? this.minWidth : this.minWidth + 'px';
  88. }
  89. var minWidth = Math.min(this.dimensions.activator.width + this.nudgeWidth + (this.auto ? 16 : 0), Math.max(this.pageWidth - 24, 0));
  90. var calculatedMaxWidth = isNaN(parseInt(this.calculatedMaxWidth)) ? minWidth : parseInt(this.calculatedMaxWidth);
  91. return Math.min(calculatedMaxWidth, minWidth) + 'px';
  92. },
  93. calculatedTop: function calculatedTop() {
  94. if (!this.auto || this.isAttached) return this.calcTop();
  95. return this.calcYOverflow(this.calculatedTopAuto) + 'px';
  96. },
  97. styles: function styles() {
  98. return {
  99. maxHeight: this.calculatedMaxHeight,
  100. minWidth: this.calculatedMinWidth,
  101. maxWidth: this.calculatedMaxWidth,
  102. top: this.calculatedTop,
  103. left: this.calculatedLeft,
  104. transformOrigin: this.origin,
  105. zIndex: this.zIndex || this.activeZIndex
  106. };
  107. }
  108. },
  109. watch: {
  110. activator: function activator(newActivator, oldActivator) {
  111. this.removeActivatorEvents(oldActivator);
  112. this.addActivatorEvents(newActivator);
  113. },
  114. disabled: function disabled(_disabled) {
  115. if (!this.activator) return;
  116. if (_disabled) {
  117. this.removeActivatorEvents(this.activator);
  118. } else {
  119. this.addActivatorEvents(this.activator);
  120. }
  121. },
  122. isContentActive: function isContentActive(val) {
  123. this.hasJustFocused = val;
  124. }
  125. },
  126. mounted: function mounted() {
  127. this.isActive && this.activate();
  128. if (getSlotType(this, 'activator', true) === 'v-slot') {
  129. consoleError('v-tooltip\'s activator slot must be bound, try \'<template #activator="data"><v-btn v-on="data.on>\'', this);
  130. }
  131. },
  132. methods: {
  133. activate: function activate() {
  134. var _this = this;
  135. // This exists primarily for v-select
  136. // helps determine which tiles to activate
  137. this.getTiles();
  138. // Update coordinates and dimensions of menu
  139. // and its activator
  140. this.updateDimensions();
  141. // Start the transition
  142. requestAnimationFrame(function () {
  143. // Once transitioning, calculate scroll and top position
  144. _this.startTransition().then(function () {
  145. if (_this.$refs.content) {
  146. _this.calculatedTopAuto = _this.calcTopAuto();
  147. _this.auto && (_this.$refs.content.scrollTop = _this.calcScrollPosition());
  148. }
  149. });
  150. });
  151. },
  152. closeConditional: function closeConditional(e) {
  153. return this.isActive && this.closeOnClick && !this.$refs.content.contains(e.target);
  154. },
  155. onResize: function onResize() {
  156. if (!this.isActive) return;
  157. // Account for screen resize
  158. // and orientation change
  159. // eslint-disable-next-line no-unused-expressions
  160. this.$refs.content.offsetWidth;
  161. this.updateDimensions();
  162. // When resizing to a smaller width
  163. // content width is evaluated before
  164. // the new activator width has been
  165. // set, causing it to not size properly
  166. // hacky but will revisit in the future
  167. clearTimeout(this.resizeTimeout);
  168. this.resizeTimeout = setTimeout(this.updateDimensions, 100);
  169. }
  170. },
  171. render: function render(h) {
  172. var data = {
  173. staticClass: 'v-menu',
  174. class: { 'v-menu--inline': !this.fullWidth && this.$slots.activator },
  175. directives: [{
  176. arg: 500,
  177. name: 'resize',
  178. value: this.onResize
  179. }],
  180. on: this.disableKeys ? undefined : {
  181. keydown: this.onKeyDown
  182. }
  183. };
  184. return h('div', data, [this.genActivator(), this.$createElement(ThemeProvider, {
  185. props: {
  186. root: true,
  187. light: this.light,
  188. dark: this.dark
  189. }
  190. }, [this.genTransition()])]);
  191. }
  192. });
  193. //# sourceMappingURL=VMenu.js.map