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.

VTabs.js 7.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. // Styles
  2. import '../../../src/stylus/components/_tabs.styl';
  3. // Extensions
  4. import { BaseItemGroup } from '../VItemGroup/VItemGroup';
  5. // Component level mixins
  6. import TabsComputed from './mixins/tabs-computed';
  7. import TabsGenerators from './mixins/tabs-generators';
  8. import TabsProps from './mixins/tabs-props';
  9. import TabsTouch from './mixins/tabs-touch';
  10. import TabsWatchers from './mixins/tabs-watchers';
  11. // Mixins
  12. import Colorable from '../../mixins/colorable';
  13. import SSRBootable from '../../mixins/ssr-bootable';
  14. import Themeable from '../../mixins/themeable';
  15. // Directives
  16. import Resize from '../../directives/resize';
  17. import Touch from '../../directives/touch';
  18. import { deprecate } from '../../util/console';
  19. // Utils
  20. import ThemeProvider from '../../util/ThemeProvider';
  21. /* @vue/component */
  22. export default BaseItemGroup.extend({
  23. name: 'v-tabs',
  24. directives: {
  25. Resize: Resize,
  26. Touch: Touch
  27. },
  28. mixins: [Colorable, SSRBootable, TabsComputed, TabsProps, TabsGenerators, TabsTouch, TabsWatchers, Themeable],
  29. provide: function provide() {
  30. return {
  31. tabGroup: this,
  32. tabProxy: this.tabProxy,
  33. registerItems: this.registerItems,
  34. unregisterItems: this.unregisterItems
  35. };
  36. },
  37. data: function data() {
  38. return {
  39. bar: [],
  40. content: [],
  41. isOverflowing: false,
  42. nextIconVisible: false,
  43. prevIconVisible: false,
  44. resizeTimeout: null,
  45. scrollOffset: 0,
  46. sliderWidth: null,
  47. sliderLeft: null,
  48. startX: 0,
  49. tabItems: null,
  50. transitionTime: 300,
  51. widths: {
  52. bar: 0,
  53. container: 0,
  54. wrapper: 0
  55. }
  56. };
  57. },
  58. watch: {
  59. items: 'onResize',
  60. tabs: 'onResize'
  61. },
  62. mounted: function mounted() {
  63. this.init();
  64. },
  65. methods: {
  66. checkIcons: function checkIcons() {
  67. this.prevIconVisible = this.checkPrevIcon();
  68. this.nextIconVisible = this.checkNextIcon();
  69. },
  70. checkPrevIcon: function checkPrevIcon() {
  71. return this.scrollOffset > 0;
  72. },
  73. checkNextIcon: function checkNextIcon() {
  74. // Check one scroll ahead to know the width of right-most item
  75. return this.widths.container > this.scrollOffset + this.widths.wrapper;
  76. },
  77. callSlider: function callSlider() {
  78. var _this = this;
  79. if (this.hideSlider || !this.activeTab) return false;
  80. // Give screen time to paint
  81. var activeTab = this.activeTab;
  82. this.$nextTick(function () {
  83. /* istanbul ignore if */
  84. if (!activeTab || !activeTab.$el) return;
  85. _this.sliderWidth = activeTab.$el.scrollWidth;
  86. _this.sliderLeft = activeTab.$el.offsetLeft;
  87. });
  88. },
  89. // Do not process
  90. // until DOM is
  91. // painted
  92. init: function init() {
  93. /* istanbul ignore next */
  94. if (this.$listeners['input']) {
  95. deprecate('@input', '@change', this);
  96. }
  97. },
  98. /**
  99. * When v-navigation-drawer changes the
  100. * width of the container, call resize
  101. * after the transition is complete
  102. */
  103. onResize: function onResize() {
  104. if (this._isDestroyed) return;
  105. this.setWidths();
  106. var delay = this.isBooted ? this.transitionTime : 0;
  107. clearTimeout(this.resizeTimeout);
  108. this.resizeTimeout = setTimeout(this.updateTabsView, delay);
  109. },
  110. overflowCheck: function overflowCheck(e, fn) {
  111. this.isOverflowing && fn(e);
  112. },
  113. scrollTo: function scrollTo(direction) {
  114. this.scrollOffset = this.newOffset(direction);
  115. },
  116. setOverflow: function setOverflow() {
  117. this.isOverflowing = this.widths.bar < this.widths.container;
  118. },
  119. setWidths: function setWidths() {
  120. var bar = this.$refs.bar ? this.$refs.bar.clientWidth : 0;
  121. var container = this.$refs.container ? this.$refs.container.clientWidth : 0;
  122. var wrapper = this.$refs.wrapper ? this.$refs.wrapper.clientWidth : 0;
  123. this.widths = { bar: bar, container: container, wrapper: wrapper };
  124. this.setOverflow();
  125. },
  126. parseNodes: function parseNodes() {
  127. var item = [];
  128. var items = [];
  129. var slider = [];
  130. var tab = [];
  131. var length = (this.$slots.default || []).length;
  132. for (var i = 0; i < length; i++) {
  133. var vnode = this.$slots.default[i];
  134. if (vnode.componentOptions) {
  135. switch (vnode.componentOptions.Ctor.options.name) {
  136. case 'v-tabs-slider':
  137. slider.push(vnode);
  138. break;
  139. case 'v-tabs-items':
  140. items.push(vnode);
  141. break;
  142. case 'v-tab-item':
  143. item.push(vnode);
  144. break;
  145. // case 'v-tab' - intentionally omitted
  146. default:
  147. tab.push(vnode);
  148. }
  149. } else {
  150. tab.push(vnode);
  151. }
  152. }
  153. return { tab: tab, slider: slider, items: items, item: item };
  154. },
  155. registerItems: function registerItems(fn) {
  156. this.tabItems = fn;
  157. fn(this.internalValue);
  158. },
  159. unregisterItems: function unregisterItems() {
  160. this.tabItems = null;
  161. },
  162. updateTabsView: function updateTabsView() {
  163. this.callSlider();
  164. this.scrollIntoView();
  165. this.checkIcons();
  166. },
  167. scrollIntoView: function scrollIntoView() {
  168. /* istanbul ignore next */
  169. if (!this.activeTab) return;
  170. if (!this.isOverflowing) return this.scrollOffset = 0;
  171. var totalWidth = this.widths.wrapper + this.scrollOffset;
  172. var _activeTab$$el = this.activeTab.$el,
  173. clientWidth = _activeTab$$el.clientWidth,
  174. offsetLeft = _activeTab$$el.offsetLeft;
  175. var itemOffset = clientWidth + offsetLeft;
  176. var additionalOffset = clientWidth * 0.3;
  177. if (this.activeTab === this.items[this.items.length - 1]) {
  178. additionalOffset = 0; // don't add an offset if selecting the last tab
  179. }
  180. /* istanbul ignore else */
  181. if (offsetLeft < this.scrollOffset) {
  182. this.scrollOffset = Math.max(offsetLeft - additionalOffset, 0);
  183. } else if (totalWidth < itemOffset) {
  184. this.scrollOffset -= totalWidth - itemOffset - additionalOffset;
  185. }
  186. },
  187. tabProxy: function tabProxy(val) {
  188. this.internalValue = val;
  189. }
  190. },
  191. render: function render(h) {
  192. var _parseNodes = this.parseNodes(),
  193. tab = _parseNodes.tab,
  194. slider = _parseNodes.slider,
  195. items = _parseNodes.items,
  196. item = _parseNodes.item;
  197. return h('div', {
  198. staticClass: 'v-tabs',
  199. directives: [{
  200. name: 'resize',
  201. modifiers: { quiet: true },
  202. value: this.onResize
  203. }]
  204. }, [this.genBar([this.hideSlider ? null : this.genSlider(slider), tab]), h(ThemeProvider, {
  205. props: { dark: this.theme.isDark, light: !this.theme.isDark }
  206. }, [this.genItems(items, item)])]);
  207. }
  208. });
  209. //# sourceMappingURL=VTabs.js.map