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.

VDialog.js 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
  2. function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
  3. import '../../../src/stylus/components/_dialogs.styl';
  4. // Mixins
  5. import Dependent from '../../mixins/dependent';
  6. import Detachable from '../../mixins/detachable';
  7. import Overlayable from '../../mixins/overlayable';
  8. import Returnable from '../../mixins/returnable';
  9. import Stackable from '../../mixins/stackable';
  10. import Toggleable from '../../mixins/toggleable';
  11. // Directives
  12. import ClickOutside from '../../directives/click-outside';
  13. // Helpers
  14. import { convertToUnit, keyCodes, getSlotType } from '../../util/helpers';
  15. import ThemeProvider from '../../util/ThemeProvider';
  16. import { consoleError } from '../../util/console';
  17. /* @vue/component */
  18. export default {
  19. name: 'v-dialog',
  20. directives: {
  21. ClickOutside: ClickOutside
  22. },
  23. mixins: [Dependent, Detachable, Overlayable, Returnable, Stackable, Toggleable],
  24. props: {
  25. disabled: Boolean,
  26. persistent: Boolean,
  27. fullscreen: Boolean,
  28. fullWidth: Boolean,
  29. noClickAnimation: Boolean,
  30. light: Boolean,
  31. dark: Boolean,
  32. maxWidth: {
  33. type: [String, Number],
  34. default: 'none'
  35. },
  36. origin: {
  37. type: String,
  38. default: 'center center'
  39. },
  40. width: {
  41. type: [String, Number],
  42. default: 'auto'
  43. },
  44. scrollable: Boolean,
  45. transition: {
  46. type: [String, Boolean],
  47. default: 'dialog-transition'
  48. }
  49. },
  50. data: function data() {
  51. return {
  52. animate: false,
  53. animateTimeout: null,
  54. stackClass: 'v-dialog__content--active',
  55. stackMinZIndex: 200
  56. };
  57. },
  58. computed: {
  59. classes: function classes() {
  60. var _ref;
  61. return _ref = {}, _defineProperty(_ref, ('v-dialog ' + this.contentClass).trim(), true), _defineProperty(_ref, 'v-dialog--active', this.isActive), _defineProperty(_ref, 'v-dialog--persistent', this.persistent), _defineProperty(_ref, 'v-dialog--fullscreen', this.fullscreen), _defineProperty(_ref, 'v-dialog--scrollable', this.scrollable), _defineProperty(_ref, 'v-dialog--animated', this.animate), _ref;
  62. },
  63. contentClasses: function contentClasses() {
  64. return {
  65. 'v-dialog__content': true,
  66. 'v-dialog__content--active': this.isActive
  67. };
  68. },
  69. hasActivator: function hasActivator() {
  70. return Boolean(!!this.$slots.activator || !!this.$scopedSlots.activator);
  71. }
  72. },
  73. watch: {
  74. isActive: function isActive(val) {
  75. if (val) {
  76. this.show();
  77. this.hideScroll();
  78. } else {
  79. this.removeOverlay();
  80. this.unbind();
  81. }
  82. },
  83. fullscreen: function fullscreen(val) {
  84. if (!this.isActive) return;
  85. if (val) {
  86. this.hideScroll();
  87. this.removeOverlay(false);
  88. } else {
  89. this.showScroll();
  90. this.genOverlay();
  91. }
  92. }
  93. },
  94. beforeMount: function beforeMount() {
  95. var _this = this;
  96. this.$nextTick(function () {
  97. _this.isBooted = _this.isActive;
  98. _this.isActive && _this.show();
  99. });
  100. },
  101. mounted: function mounted() {
  102. if (getSlotType(this, 'activator', true) === 'v-slot') {
  103. consoleError('v-dialog\'s activator slot must be bound, try \'<template #activator="data"><v-btn v-on="data.on>\'', this);
  104. }
  105. },
  106. beforeDestroy: function beforeDestroy() {
  107. if (typeof window !== 'undefined') this.unbind();
  108. },
  109. methods: {
  110. animateClick: function animateClick() {
  111. var _this2 = this;
  112. this.animate = false;
  113. // Needed for when clicking very fast
  114. // outside of the dialog
  115. this.$nextTick(function () {
  116. _this2.animate = true;
  117. clearTimeout(_this2.animateTimeout);
  118. _this2.animateTimeout = setTimeout(function () {
  119. return _this2.animate = false;
  120. }, 150);
  121. });
  122. },
  123. closeConditional: function closeConditional(e) {
  124. // If the dialog content contains
  125. // the click event, or if the
  126. // dialog is not active
  127. if (!this.isActive || this.$refs.content.contains(e.target)) return false;
  128. // If we made it here, the click is outside
  129. // and is active. If persistent, and the
  130. // click is on the overlay, animate
  131. if (this.persistent) {
  132. if (!this.noClickAnimation && this.overlay === e.target) this.animateClick();
  133. return false;
  134. }
  135. // close dialog if !persistent, clicked outside and we're the topmost dialog.
  136. // Since this should only be called in a capture event (bottom up), we shouldn't need to stop propagation
  137. return this.activeZIndex >= this.getMaxZIndex();
  138. },
  139. hideScroll: function hideScroll() {
  140. if (this.fullscreen) {
  141. document.documentElement.classList.add('overflow-y-hidden');
  142. } else {
  143. Overlayable.options.methods.hideScroll.call(this);
  144. }
  145. },
  146. show: function show() {
  147. !this.fullscreen && !this.hideOverlay && this.genOverlay();
  148. this.$refs.content.focus();
  149. this.bind();
  150. },
  151. bind: function bind() {
  152. window.addEventListener('focusin', this.onFocusin);
  153. },
  154. unbind: function unbind() {
  155. window.removeEventListener('focusin', this.onFocusin);
  156. },
  157. onKeydown: function onKeydown(e) {
  158. if (e.keyCode === keyCodes.esc && !this.getOpenDependents().length) {
  159. if (!this.persistent) {
  160. this.isActive = false;
  161. var activator = this.getActivator();
  162. this.$nextTick(function () {
  163. return activator && activator.focus();
  164. });
  165. } else if (!this.noClickAnimation) {
  166. this.animateClick();
  167. }
  168. }
  169. this.$emit('keydown', e);
  170. },
  171. onFocusin: function onFocusin(e) {
  172. var _event = event,
  173. target = _event.target;
  174. if (
  175. // It isn't the document or the dialog body
  176. ![document, this.$refs.content].includes(target) &&
  177. // It isn't inside the dialog body
  178. !this.$refs.content.contains(target) &&
  179. // We're the topmost dialog
  180. this.activeZIndex >= this.getMaxZIndex() &&
  181. // It isn't inside a dependent element (like a menu)
  182. !this.getOpenDependentElements().some(function (el) {
  183. return el.contains(target);
  184. })
  185. // So we must have focused something outside the dialog and its children
  186. ) {
  187. // Find and focus the first available element inside the dialog
  188. var focusable = this.$refs.content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
  189. focusable.length && focusable[0].focus();
  190. }
  191. },
  192. getActivator: function getActivator(e) {
  193. if (this.$refs.activator) {
  194. return this.$refs.activator.children.length > 0 ? this.$refs.activator.children[0] : this.$refs.activator;
  195. }
  196. if (e) {
  197. this.activatedBy = e.currentTarget || e.target;
  198. }
  199. if (this.activatedBy) return this.activatedBy;
  200. if (this.activatorNode) {
  201. var activator = Array.isArray(this.activatorNode) ? this.activatorNode[0] : this.activatorNode;
  202. var el = activator && activator.elm;
  203. if (el) return el;
  204. }
  205. consoleError('No activator found');
  206. },
  207. genActivator: function genActivator() {
  208. var _this3 = this;
  209. if (!this.hasActivator) return null;
  210. var listeners = this.disabled ? {} : {
  211. click: function click(e) {
  212. e.stopPropagation();
  213. _this3.getActivator(e);
  214. if (!_this3.disabled) _this3.isActive = !_this3.isActive;
  215. }
  216. };
  217. if (getSlotType(this, 'activator') === 'scoped') {
  218. var activator = this.$scopedSlots.activator({ on: listeners });
  219. this.activatorNode = activator;
  220. return activator;
  221. }
  222. return this.$createElement('div', {
  223. staticClass: 'v-dialog__activator',
  224. class: {
  225. 'v-dialog__activator--disabled': this.disabled
  226. },
  227. ref: 'activator',
  228. on: listeners
  229. }, this.$slots.activator);
  230. }
  231. },
  232. render: function render(h) {
  233. var _this4 = this;
  234. var children = [];
  235. var data = {
  236. 'class': this.classes,
  237. ref: 'dialog',
  238. directives: [{
  239. name: 'click-outside',
  240. value: function value() {
  241. _this4.isActive = false;
  242. },
  243. args: {
  244. closeConditional: this.closeConditional,
  245. include: this.getOpenDependentElements
  246. }
  247. }, { name: 'show', value: this.isActive }],
  248. on: {
  249. click: function click(e) {
  250. e.stopPropagation();
  251. }
  252. }
  253. };
  254. if (!this.fullscreen) {
  255. data.style = {
  256. maxWidth: this.maxWidth === 'none' ? undefined : convertToUnit(this.maxWidth),
  257. width: this.width === 'auto' ? undefined : convertToUnit(this.width)
  258. };
  259. }
  260. children.push(this.genActivator());
  261. var dialog = h('div', data, this.showLazyContent(this.$slots.default));
  262. if (this.transition) {
  263. dialog = h('transition', {
  264. props: {
  265. name: this.transition,
  266. origin: this.origin
  267. }
  268. }, [dialog]);
  269. }
  270. children.push(h('div', {
  271. 'class': this.contentClasses,
  272. attrs: _extends({
  273. tabIndex: '-1'
  274. }, this.getScopeIdAttrs()),
  275. on: {
  276. keydown: this.onKeydown
  277. },
  278. style: { zIndex: this.activeZIndex },
  279. ref: 'content'
  280. }, [this.$createElement(ThemeProvider, {
  281. props: {
  282. root: true,
  283. light: this.light,
  284. dark: this.dark
  285. }
  286. }, [dialog])]));
  287. return h('div', {
  288. staticClass: 'v-dialog__container',
  289. style: {
  290. display: !this.hasActivator || this.fullWidth ? 'block' : 'inline-block'
  291. }
  292. }, children);
  293. }
  294. };
  295. //# sourceMappingURL=VDialog.js.map