vuetify eingebunden + erster Versuch Combobox
This commit is contained in:
+197
@@ -0,0 +1,197 @@
|
||||
import '../../../src/stylus/components/_menus.styl';
|
||||
import Vue from 'vue';
|
||||
// Mixins
|
||||
import Delayable from '../../mixins/delayable';
|
||||
import Dependent from '../../mixins/dependent';
|
||||
import Detachable from '../../mixins/detachable';
|
||||
import Menuable from '../../mixins/menuable.js';
|
||||
import Returnable from '../../mixins/returnable';
|
||||
import Toggleable from '../../mixins/toggleable';
|
||||
import Themeable from '../../mixins/themeable';
|
||||
// Component level mixins
|
||||
import Activator from './mixins/menu-activator';
|
||||
import Generators from './mixins/menu-generators';
|
||||
import Keyable from './mixins/menu-keyable';
|
||||
import Position from './mixins/menu-position';
|
||||
// Directives
|
||||
import ClickOutside from '../../directives/click-outside';
|
||||
import Resize from '../../directives/resize';
|
||||
// Helpers
|
||||
import { convertToUnit, getSlotType } from '../../util/helpers';
|
||||
import ThemeProvider from '../../util/ThemeProvider';
|
||||
import { consoleError } from '../../util/console';
|
||||
/* @vue/component */
|
||||
export default Vue.extend({
|
||||
name: 'v-menu',
|
||||
provide: function provide() {
|
||||
return {
|
||||
// Pass theme through to default slot
|
||||
theme: this.theme
|
||||
};
|
||||
},
|
||||
|
||||
directives: {
|
||||
ClickOutside: ClickOutside,
|
||||
Resize: Resize
|
||||
},
|
||||
mixins: [Activator, Dependent, Delayable, Detachable, Generators, Keyable, Menuable, Position, Returnable, Toggleable, Themeable],
|
||||
props: {
|
||||
auto: Boolean,
|
||||
closeOnClick: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
closeOnContentClick: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
disabled: Boolean,
|
||||
fullWidth: Boolean,
|
||||
maxHeight: { default: 'auto' },
|
||||
openOnClick: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
offsetX: Boolean,
|
||||
offsetY: Boolean,
|
||||
openOnHover: Boolean,
|
||||
origin: {
|
||||
type: String,
|
||||
default: 'top left'
|
||||
},
|
||||
transition: {
|
||||
type: [Boolean, String],
|
||||
default: 'v-menu-transition'
|
||||
}
|
||||
},
|
||||
data: function data() {
|
||||
return {
|
||||
defaultOffset: 8,
|
||||
hasJustFocused: false,
|
||||
resizeTimeout: null
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
calculatedLeft: function calculatedLeft() {
|
||||
var menuWidth = Math.max(this.dimensions.content.width, parseFloat(this.calculatedMinWidth));
|
||||
if (!this.auto) return this.calcLeft(menuWidth);
|
||||
return this.calcXOverflow(this.calcLeftAuto(), menuWidth) + 'px';
|
||||
},
|
||||
calculatedMaxHeight: function calculatedMaxHeight() {
|
||||
return this.auto ? '200px' : convertToUnit(this.maxHeight);
|
||||
},
|
||||
calculatedMaxWidth: function calculatedMaxWidth() {
|
||||
return isNaN(this.maxWidth) ? this.maxWidth : this.maxWidth + 'px';
|
||||
},
|
||||
calculatedMinWidth: function calculatedMinWidth() {
|
||||
if (this.minWidth) {
|
||||
return isNaN(this.minWidth) ? this.minWidth : this.minWidth + 'px';
|
||||
}
|
||||
var minWidth = Math.min(this.dimensions.activator.width + this.nudgeWidth + (this.auto ? 16 : 0), Math.max(this.pageWidth - 24, 0));
|
||||
var calculatedMaxWidth = isNaN(parseInt(this.calculatedMaxWidth)) ? minWidth : parseInt(this.calculatedMaxWidth);
|
||||
return Math.min(calculatedMaxWidth, minWidth) + 'px';
|
||||
},
|
||||
calculatedTop: function calculatedTop() {
|
||||
if (!this.auto || this.isAttached) return this.calcTop();
|
||||
return this.calcYOverflow(this.calculatedTopAuto) + 'px';
|
||||
},
|
||||
styles: function styles() {
|
||||
return {
|
||||
maxHeight: this.calculatedMaxHeight,
|
||||
minWidth: this.calculatedMinWidth,
|
||||
maxWidth: this.calculatedMaxWidth,
|
||||
top: this.calculatedTop,
|
||||
left: this.calculatedLeft,
|
||||
transformOrigin: this.origin,
|
||||
zIndex: this.zIndex || this.activeZIndex
|
||||
};
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
activator: function activator(newActivator, oldActivator) {
|
||||
this.removeActivatorEvents(oldActivator);
|
||||
this.addActivatorEvents(newActivator);
|
||||
},
|
||||
disabled: function disabled(_disabled) {
|
||||
if (!this.activator) return;
|
||||
if (_disabled) {
|
||||
this.removeActivatorEvents(this.activator);
|
||||
} else {
|
||||
this.addActivatorEvents(this.activator);
|
||||
}
|
||||
},
|
||||
isContentActive: function isContentActive(val) {
|
||||
this.hasJustFocused = val;
|
||||
}
|
||||
},
|
||||
mounted: function mounted() {
|
||||
this.isActive && this.activate();
|
||||
if (getSlotType(this, 'activator', true) === 'v-slot') {
|
||||
consoleError('v-tooltip\'s activator slot must be bound, try \'<template #activator="data"><v-btn v-on="data.on>\'', this);
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
activate: function activate() {
|
||||
var _this = this;
|
||||
|
||||
// This exists primarily for v-select
|
||||
// helps determine which tiles to activate
|
||||
this.getTiles();
|
||||
// Update coordinates and dimensions of menu
|
||||
// and its activator
|
||||
this.updateDimensions();
|
||||
// Start the transition
|
||||
requestAnimationFrame(function () {
|
||||
// Once transitioning, calculate scroll and top position
|
||||
_this.startTransition().then(function () {
|
||||
if (_this.$refs.content) {
|
||||
_this.calculatedTopAuto = _this.calcTopAuto();
|
||||
_this.auto && (_this.$refs.content.scrollTop = _this.calcScrollPosition());
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
closeConditional: function closeConditional(e) {
|
||||
return this.isActive && this.closeOnClick && !this.$refs.content.contains(e.target);
|
||||
},
|
||||
onResize: function onResize() {
|
||||
if (!this.isActive) return;
|
||||
// Account for screen resize
|
||||
// and orientation change
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
this.$refs.content.offsetWidth;
|
||||
this.updateDimensions();
|
||||
// When resizing to a smaller width
|
||||
// content width is evaluated before
|
||||
// the new activator width has been
|
||||
// set, causing it to not size properly
|
||||
// hacky but will revisit in the future
|
||||
clearTimeout(this.resizeTimeout);
|
||||
this.resizeTimeout = setTimeout(this.updateDimensions, 100);
|
||||
}
|
||||
},
|
||||
render: function render(h) {
|
||||
var data = {
|
||||
staticClass: 'v-menu',
|
||||
class: { 'v-menu--inline': !this.fullWidth && this.$slots.activator },
|
||||
directives: [{
|
||||
arg: 500,
|
||||
name: 'resize',
|
||||
value: this.onResize
|
||||
}],
|
||||
on: this.disableKeys ? undefined : {
|
||||
keydown: this.onKeyDown
|
||||
}
|
||||
};
|
||||
return h('div', data, [this.genActivator(), this.$createElement(ThemeProvider, {
|
||||
props: {
|
||||
root: true,
|
||||
light: this.light,
|
||||
dark: this.dark
|
||||
}
|
||||
}, [this.genTransition()])]);
|
||||
}
|
||||
});
|
||||
//# sourceMappingURL=VMenu.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
+4
@@ -0,0 +1,4 @@
|
||||
import VMenu from './VMenu';
|
||||
export { VMenu };
|
||||
export default VMenu;
|
||||
//# sourceMappingURL=index.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../../../src/components/VMenu/index.js"],"names":[],"mappings":"AAAA,OAAO,KAAP,MAAkB,SAAlB;AAEA,SAAS,KAAT;AACA,eAAe,KAAf","sourcesContent":["import VMenu from './VMenu'\n\nexport { VMenu }\nexport default VMenu\n"],"sourceRoot":""}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* Menu activator
|
||||
*
|
||||
* @mixin
|
||||
*
|
||||
* Handles the click and hover activation
|
||||
* Supports slotted and detached activators
|
||||
*/
|
||||
/* @vue/component */
|
||||
export default {
|
||||
methods: {
|
||||
activatorClickHandler: function activatorClickHandler(e) {
|
||||
if (this.openOnClick && !this.isActive) {
|
||||
this.getActivator(e).focus();
|
||||
this.isActive = true;
|
||||
this.absoluteX = e.clientX;
|
||||
this.absoluteY = e.clientY;
|
||||
} else if (this.closeOnClick && this.isActive) {
|
||||
this.getActivator(e).blur();
|
||||
this.isActive = false;
|
||||
}
|
||||
},
|
||||
mouseEnterHandler: function mouseEnterHandler() {
|
||||
var _this = this;
|
||||
|
||||
this.runDelay('open', function () {
|
||||
if (_this.hasJustFocused) return;
|
||||
_this.hasJustFocused = true;
|
||||
_this.isActive = true;
|
||||
});
|
||||
},
|
||||
mouseLeaveHandler: function mouseLeaveHandler(e) {
|
||||
var _this2 = this;
|
||||
|
||||
// Prevent accidental re-activation
|
||||
this.runDelay('close', function () {
|
||||
if (_this2.$refs.content.contains(e.relatedTarget)) return;
|
||||
requestAnimationFrame(function () {
|
||||
_this2.isActive = false;
|
||||
_this2.callDeactivate();
|
||||
});
|
||||
});
|
||||
},
|
||||
addActivatorEvents: function addActivatorEvents() {
|
||||
var activator = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
|
||||
|
||||
if (!activator || this.disabled) return;
|
||||
activator.addEventListener('click', this.activatorClickHandler);
|
||||
},
|
||||
removeActivatorEvents: function removeActivatorEvents() {
|
||||
var activator = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
|
||||
|
||||
if (!activator) return;
|
||||
activator.removeEventListener('click', this.activatorClickHandler);
|
||||
}
|
||||
}
|
||||
};
|
||||
//# sourceMappingURL=menu-activator.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../../../../src/components/VMenu/mixins/menu-activator.js"],"names":[],"mappings":";;;;;;;;AAQA;AACA,eAAe;AACb,aAAS;AACP,6BADO,iCACgB,CADhB,EACiB;AACtB,gBAAI,KAAK,WAAL,IAAoB,CAAC,KAAK,QAA9B,EAAwC;AACtC,qBAAK,YAAL,CAAkB,CAAlB,EAAqB,KAArB;AACA,qBAAK,QAAL,GAAgB,IAAhB;AACA,qBAAK,SAAL,GAAiB,EAAE,OAAnB;AACA,qBAAK,SAAL,GAAiB,EAAE,OAAnB;AACD,aALD,MAKO,IAAI,KAAK,YAAL,IAAqB,KAAK,QAA9B,EAAwC;AAC7C,qBAAK,YAAL,CAAkB,CAAlB,EAAqB,IAArB;AACA,qBAAK,QAAL,GAAgB,KAAhB;AACD;AACF,SAXM;AAYP,yBAZO,+BAYU;AAAA;;AACf,iBAAK,QAAL,CAAc,MAAd,EAAsB,YAAK;AACzB,oBAAI,MAAK,cAAT,EAAyB;AAEzB,sBAAK,cAAL,GAAsB,IAAtB;AACA,sBAAK,QAAL,GAAgB,IAAhB;AACD,aALD;AAMD,SAnBM;AAoBP,yBApBO,6BAoBY,CApBZ,EAoBa;AAAA;;AAClB;AACA,iBAAK,QAAL,CAAc,OAAd,EAAuB,YAAK;AAC1B,oBAAI,OAAK,KAAL,CAAW,OAAX,CAAmB,QAAnB,CAA4B,EAAE,aAA9B,CAAJ,EAAkD;AAElD,sCAAsB,YAAK;AACzB,2BAAK,QAAL,GAAgB,KAAhB;AACA,2BAAK,cAAL;AACD,iBAHD;AAID,aAPD;AAQD,SA9BM;AA+BP,0BA/BO,gCA+B6B;AAAA,gBAAhB,SAAgB,uEAAJ,IAAI;;AAClC,gBAAI,CAAC,SAAD,IAAc,KAAK,QAAvB,EAAiC;AACjC,sBAAU,gBAAV,CAA2B,OAA3B,EAAoC,KAAK,qBAAzC;AACD,SAlCM;AAmCP,6BAnCO,mCAmCgC;AAAA,gBAAhB,SAAgB,uEAAJ,IAAI;;AACrC,gBAAI,CAAC,SAAL,EAAgB;AAChB,sBAAU,mBAAV,CAA8B,OAA9B,EAAuC,KAAK,qBAA5C;AACD;AAtCM;AADI,CAAf","sourcesContent":["/**\n * Menu activator\n *\n * @mixin\n *\n * Handles the click and hover activation\n * Supports slotted and detached activators\n */\n/* @vue/component */\nexport default {\n methods: {\n activatorClickHandler (e) {\n if (this.openOnClick && !this.isActive) {\n this.getActivator(e).focus()\n this.isActive = true\n this.absoluteX = e.clientX\n this.absoluteY = e.clientY\n } else if (this.closeOnClick && this.isActive) {\n this.getActivator(e).blur()\n this.isActive = false\n }\n },\n mouseEnterHandler () {\n this.runDelay('open', () => {\n if (this.hasJustFocused) return\n\n this.hasJustFocused = true\n this.isActive = true\n })\n },\n mouseLeaveHandler (e) {\n // Prevent accidental re-activation\n this.runDelay('close', () => {\n if (this.$refs.content.contains(e.relatedTarget)) return\n\n requestAnimationFrame(() => {\n this.isActive = false\n this.callDeactivate()\n })\n })\n },\n addActivatorEvents (activator = null) {\n if (!activator || this.disabled) return\n activator.addEventListener('click', this.activatorClickHandler)\n },\n removeActivatorEvents (activator = null) {\n if (!activator) return\n activator.removeEventListener('click', this.activatorClickHandler)\n }\n }\n}\n"],"sourceRoot":""}
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
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; };
|
||||
|
||||
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; }
|
||||
|
||||
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
|
||||
|
||||
import { getSlotType } from '../../../util/helpers';
|
||||
/* @vue/component */
|
||||
export default {
|
||||
methods: {
|
||||
genActivator: function genActivator() {
|
||||
if (!this.$slots.activator && !this.$scopedSlots.activator) return null;
|
||||
var listeners = {};
|
||||
if (!this.disabled) {
|
||||
if (this.openOnHover) {
|
||||
listeners.mouseenter = this.mouseEnterHandler;
|
||||
listeners.mouseleave = this.mouseLeaveHandler;
|
||||
} else if (this.openOnClick) {
|
||||
listeners.click = this.activatorClickHandler;
|
||||
}
|
||||
}
|
||||
if (getSlotType(this, 'activator') === 'scoped') {
|
||||
listeners.keydown = this.onKeyDown;
|
||||
var activator = this.$scopedSlots.activator({ on: listeners });
|
||||
this.activatorNode = activator;
|
||||
return activator;
|
||||
}
|
||||
return this.$createElement('div', {
|
||||
staticClass: 'v-menu__activator',
|
||||
'class': {
|
||||
'v-menu__activator--active': this.hasJustFocused || this.isActive,
|
||||
'v-menu__activator--disabled': this.disabled
|
||||
},
|
||||
ref: 'activator',
|
||||
on: listeners
|
||||
}, this.$slots.activator);
|
||||
},
|
||||
genTransition: function genTransition() {
|
||||
if (!this.transition) return this.genContent();
|
||||
return this.$createElement('transition', {
|
||||
props: {
|
||||
name: this.transition
|
||||
}
|
||||
}, [this.genContent()]);
|
||||
},
|
||||
genDirectives: function genDirectives() {
|
||||
var _this = this;
|
||||
|
||||
// Do not add click outside for hover menu
|
||||
var directives = !this.openOnHover && this.closeOnClick ? [{
|
||||
name: 'click-outside',
|
||||
value: function value() {
|
||||
_this.isActive = false;
|
||||
},
|
||||
args: {
|
||||
closeConditional: this.closeConditional,
|
||||
include: function include() {
|
||||
return [_this.$el].concat(_toConsumableArray(_this.getOpenDependentElements()));
|
||||
}
|
||||
}
|
||||
}] : [];
|
||||
directives.push({
|
||||
name: 'show',
|
||||
value: this.isContentActive
|
||||
});
|
||||
return directives;
|
||||
},
|
||||
genContent: function genContent() {
|
||||
var _this2 = this;
|
||||
|
||||
var options = {
|
||||
attrs: this.getScopeIdAttrs(),
|
||||
staticClass: 'v-menu__content',
|
||||
'class': _extends({}, this.rootThemeClasses, _defineProperty({
|
||||
'v-menu__content--auto': this.auto,
|
||||
'v-menu__content--fixed': this.activatorFixed,
|
||||
'menuable__content__active': this.isActive
|
||||
}, this.contentClass.trim(), true)),
|
||||
style: this.styles,
|
||||
directives: this.genDirectives(),
|
||||
ref: 'content',
|
||||
on: {
|
||||
click: function click(e) {
|
||||
e.stopPropagation();
|
||||
if (e.target.getAttribute('disabled')) return;
|
||||
if (_this2.closeOnContentClick) _this2.isActive = false;
|
||||
},
|
||||
keydown: this.onKeyDown
|
||||
}
|
||||
};
|
||||
!this.disabled && this.openOnHover && (options.on.mouseenter = this.mouseEnterHandler);
|
||||
this.openOnHover && (options.on.mouseleave = this.mouseLeaveHandler);
|
||||
return this.$createElement('div', options, this.showLazyContent(this.$slots.default));
|
||||
}
|
||||
}
|
||||
};
|
||||
//# sourceMappingURL=menu-generators.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
+81
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* Menu keyable
|
||||
*
|
||||
* @mixin
|
||||
*
|
||||
* Primarily used to support VSelect
|
||||
* Handles opening and closing of VMenu from keystrokes
|
||||
* Will conditionally highlight VListTiles for VSelect
|
||||
*/
|
||||
// Utils
|
||||
import { keyCodes } from '../../../util/helpers';
|
||||
/* @vue/component */
|
||||
export default {
|
||||
props: {
|
||||
disableKeys: Boolean
|
||||
},
|
||||
data: function data() {
|
||||
return {
|
||||
listIndex: -1,
|
||||
tiles: []
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
isActive: function isActive(val) {
|
||||
if (!val) this.listIndex = -1;
|
||||
},
|
||||
listIndex: function listIndex(next, prev) {
|
||||
if (next in this.tiles) {
|
||||
var tile = this.tiles[next];
|
||||
tile.classList.add('v-list__tile--highlighted');
|
||||
this.$refs.content.scrollTop = tile.offsetTop - tile.clientHeight;
|
||||
}
|
||||
prev in this.tiles && this.tiles[prev].classList.remove('v-list__tile--highlighted');
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onKeyDown: function onKeyDown(e) {
|
||||
var _this = this;
|
||||
|
||||
if (e.keyCode === keyCodes.esc) {
|
||||
// Wait for dependent elements to close first
|
||||
setTimeout(function () {
|
||||
_this.isActive = false;
|
||||
});
|
||||
var activator = this.getActivator();
|
||||
this.$nextTick(function () {
|
||||
return activator && activator.focus();
|
||||
});
|
||||
} else if (e.keyCode === keyCodes.tab) {
|
||||
setTimeout(function () {
|
||||
if (!_this.$refs.content.contains(document.activeElement)) {
|
||||
_this.isActive = false;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.changeListIndex(e);
|
||||
}
|
||||
},
|
||||
changeListIndex: function changeListIndex(e) {
|
||||
// For infinite scroll and autocomplete, re-evaluate children
|
||||
this.getTiles();
|
||||
if (e.keyCode === keyCodes.down && this.listIndex < this.tiles.length - 1) {
|
||||
this.listIndex++;
|
||||
// Allow user to set listIndex to -1 so
|
||||
// that the list can be un-highlighted
|
||||
} else if (e.keyCode === keyCodes.up && this.listIndex > -1) {
|
||||
this.listIndex--;
|
||||
} else if (e.keyCode === keyCodes.enter && this.listIndex !== -1) {
|
||||
this.tiles[this.listIndex].click();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
// One of the conditions was met, prevent default action (#2988)
|
||||
e.preventDefault();
|
||||
},
|
||||
getTiles: function getTiles() {
|
||||
this.tiles = this.$refs.content.querySelectorAll('.v-list__tile');
|
||||
}
|
||||
}
|
||||
};
|
||||
//# sourceMappingURL=menu-keyable.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../../../../src/components/VMenu/mixins/menu-keyable.js"],"names":[],"mappings":";;;;;;;;;AAUA;AACA,SAAS,QAAT,QAAyB,uBAAzB;AAEA;AACA,eAAe;AACb,WAAO;AACL,qBAAa;AADR,KADM;AAKb,UAAM;AAAA,eAAO;AACX,uBAAW,CAAC,CADD;AAEX,mBAAO;AAFI,SAAP;AAAA,KALO;AAUb,WAAO;AACL,gBADK,oBACK,GADL,EACQ;AACX,gBAAI,CAAC,GAAL,EAAU,KAAK,SAAL,GAAiB,CAAC,CAAlB;AACX,SAHI;AAIL,iBAJK,qBAIM,IAJN,EAIY,IAJZ,EAIgB;AACnB,gBAAI,QAAQ,KAAK,KAAjB,EAAwB;AACtB,oBAAM,OAAO,KAAK,KAAL,CAAW,IAAX,CAAb;AACA,qBAAK,SAAL,CAAe,GAAf,CAAmB,2BAAnB;AACA,qBAAK,KAAL,CAAW,OAAX,CAAmB,SAAnB,GAA+B,KAAK,SAAL,GAAiB,KAAK,YAArD;AACD;AAED,oBAAQ,KAAK,KAAb,IACE,KAAK,KAAL,CAAW,IAAX,EAAiB,SAAjB,CAA2B,MAA3B,CAAkC,2BAAlC,CADF;AAED;AAbI,KAVM;AA0Bb,aAAS;AACP,iBADO,qBACI,CADJ,EACK;AAAA;;AACV,gBAAI,EAAE,OAAF,KAAc,SAAS,GAA3B,EAAgC;AAC9B;AACA,2BAAW,YAAK;AAAG,0BAAK,QAAL,GAAgB,KAAhB;AAAuB,iBAA1C;AACA,oBAAM,YAAY,KAAK,YAAL,EAAlB;AACA,qBAAK,SAAL,CAAe;AAAA,2BAAM,aAAa,UAAU,KAAV,EAAnB;AAAA,iBAAf;AACD,aALD,MAKO,IAAI,EAAE,OAAF,KAAc,SAAS,GAA3B,EAAgC;AACrC,2BAAW,YAAK;AACd,wBAAI,CAAC,MAAK,KAAL,CAAW,OAAX,CAAmB,QAAnB,CAA4B,SAAS,aAArC,CAAL,EAA0D;AACxD,8BAAK,QAAL,GAAgB,KAAhB;AACD;AACF,iBAJD;AAKD,aANM,MAMA;AACL,qBAAK,eAAL,CAAqB,CAArB;AACD;AACF,SAhBM;AAiBP,uBAjBO,2BAiBU,CAjBV,EAiBW;AAChB;AACA,iBAAK,QAAL;AAEA,gBAAI,EAAE,OAAF,KAAc,SAAS,IAAvB,IAA+B,KAAK,SAAL,GAAiB,KAAK,KAAL,CAAW,MAAX,GAAoB,CAAxE,EAA2E;AACzE,qBAAK,SAAL;AACA;AACA;AACD,aAJD,MAIO,IAAI,EAAE,OAAF,KAAc,SAAS,EAAvB,IAA6B,KAAK,SAAL,GAAiB,CAAC,CAAnD,EAAsD;AAC3D,qBAAK,SAAL;AACD,aAFM,MAEA,IAAI,EAAE,OAAF,KAAc,SAAS,KAAvB,IAAgC,KAAK,SAAL,KAAmB,CAAC,CAAxD,EAA2D;AAChE,qBAAK,KAAL,CAAW,KAAK,SAAhB,EAA2B,KAA3B;AACD,aAFM,MAEA;AAAE;AAAQ;AACjB;AACA,cAAE,cAAF;AACD,SAhCM;AAiCP,gBAjCO,sBAiCC;AACN,iBAAK,KAAL,GAAa,KAAK,KAAL,CAAW,OAAX,CAAmB,gBAAnB,CAAoC,eAApC,CAAb;AACD;AAnCM;AA1BI,CAAf","sourcesContent":["/**\n * Menu keyable\n *\n * @mixin\n *\n * Primarily used to support VSelect\n * Handles opening and closing of VMenu from keystrokes\n * Will conditionally highlight VListTiles for VSelect\n */\n\n// Utils\nimport { keyCodes } from '../../../util/helpers'\n\n/* @vue/component */\nexport default {\n props: {\n disableKeys: Boolean\n },\n\n data: () => ({\n listIndex: -1,\n tiles: []\n }),\n\n watch: {\n isActive (val) {\n if (!val) this.listIndex = -1\n },\n listIndex (next, prev) {\n if (next in this.tiles) {\n const tile = this.tiles[next]\n tile.classList.add('v-list__tile--highlighted')\n this.$refs.content.scrollTop = tile.offsetTop - tile.clientHeight\n }\n\n prev in this.tiles &&\n this.tiles[prev].classList.remove('v-list__tile--highlighted')\n }\n },\n\n methods: {\n onKeyDown (e) {\n if (e.keyCode === keyCodes.esc) {\n // Wait for dependent elements to close first\n setTimeout(() => { this.isActive = false })\n const activator = this.getActivator()\n this.$nextTick(() => activator && activator.focus())\n } else if (e.keyCode === keyCodes.tab) {\n setTimeout(() => {\n if (!this.$refs.content.contains(document.activeElement)) {\n this.isActive = false\n }\n })\n } else {\n this.changeListIndex(e)\n }\n },\n changeListIndex (e) {\n // For infinite scroll and autocomplete, re-evaluate children\n this.getTiles()\n\n if (e.keyCode === keyCodes.down && this.listIndex < this.tiles.length - 1) {\n this.listIndex++\n // Allow user to set listIndex to -1 so\n // that the list can be un-highlighted\n } else if (e.keyCode === keyCodes.up && this.listIndex > -1) {\n this.listIndex--\n } else if (e.keyCode === keyCodes.enter && this.listIndex !== -1) {\n this.tiles[this.listIndex].click()\n } else { return }\n // One of the conditions was met, prevent default action (#2988)\n e.preventDefault()\n },\n getTiles () {\n this.tiles = this.$refs.content.querySelectorAll('.v-list__tile')\n }\n }\n}\n"],"sourceRoot":""}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Menu position
|
||||
*
|
||||
* @mixin
|
||||
*
|
||||
* Used for calculating an automatic position (used for VSelect)
|
||||
* Will position the VMenu content properly over the VSelect
|
||||
*/
|
||||
/* @vue/component */
|
||||
export default {
|
||||
data: function data() {
|
||||
return {
|
||||
calculatedTopAuto: 0
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
calcScrollPosition: function calcScrollPosition() {
|
||||
var $el = this.$refs.content;
|
||||
var activeTile = $el.querySelector('.v-list__tile--active');
|
||||
var maxScrollTop = $el.scrollHeight - $el.offsetHeight;
|
||||
return activeTile ? Math.min(maxScrollTop, Math.max(0, activeTile.offsetTop - $el.offsetHeight / 2 + activeTile.offsetHeight / 2)) : $el.scrollTop;
|
||||
},
|
||||
calcLeftAuto: function calcLeftAuto() {
|
||||
if (this.isAttached) return 0;
|
||||
return parseInt(this.dimensions.activator.left - this.defaultOffset * 2);
|
||||
},
|
||||
calcTopAuto: function calcTopAuto() {
|
||||
var $el = this.$refs.content;
|
||||
var activeTile = $el.querySelector('.v-list__tile--active');
|
||||
if (!activeTile) {
|
||||
this.selectedIndex = null;
|
||||
}
|
||||
if (this.offsetY || !activeTile) {
|
||||
return this.computedTop;
|
||||
}
|
||||
this.selectedIndex = Array.from(this.tiles).indexOf(activeTile);
|
||||
var tileDistanceFromMenuTop = activeTile.offsetTop - this.calcScrollPosition();
|
||||
var firstTileOffsetTop = $el.querySelector('.v-list__tile').offsetTop;
|
||||
return this.computedTop - tileDistanceFromMenuTop - firstTileOffsetTop;
|
||||
}
|
||||
}
|
||||
};
|
||||
//# sourceMappingURL=menu-position.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../../../../src/components/VMenu/mixins/menu-position.js"],"names":[],"mappings":";;;;;;;;AAQA;AACA,eAAe;AACb,UAAM;AAAA,eAAO;AACX,+BAAmB;AADR,SAAP;AAAA,KADO;AAIb,aAAS;AACP,0BADO,gCACW;AAChB,gBAAM,MAAM,KAAK,KAAL,CAAW,OAAvB;AACA,gBAAM,aAAa,IAAI,aAAJ,CAAkB,uBAAlB,CAAnB;AACA,gBAAM,eAAe,IAAI,YAAJ,GAAmB,IAAI,YAA5C;AAEA,mBAAO,aACH,KAAK,GAAL,CAAS,YAAT,EAAuB,KAAK,GAAL,CAAS,CAAT,EAAY,WAAW,SAAX,GAAuB,IAAI,YAAJ,GAAmB,CAA1C,GAA8C,WAAW,YAAX,GAA0B,CAApF,CAAvB,CADG,GAEH,IAAI,SAFR;AAGD,SATM;AAUP,oBAVO,0BAUK;AACV,gBAAI,KAAK,UAAT,EAAqB,OAAO,CAAP;AAErB,mBAAO,SAAS,KAAK,UAAL,CAAgB,SAAhB,CAA0B,IAA1B,GAAiC,KAAK,aAAL,GAAqB,CAA/D,CAAP;AACD,SAdM;AAeP,mBAfO,yBAeI;AACT,gBAAM,MAAM,KAAK,KAAL,CAAW,OAAvB;AACA,gBAAM,aAAa,IAAI,aAAJ,CAAkB,uBAAlB,CAAnB;AAEA,gBAAI,CAAC,UAAL,EAAiB;AACf,qBAAK,aAAL,GAAqB,IAArB;AACD;AAED,gBAAI,KAAK,OAAL,IAAgB,CAAC,UAArB,EAAiC;AAC/B,uBAAO,KAAK,WAAZ;AACD;AAED,iBAAK,aAAL,GAAqB,MAAM,IAAN,CAAW,KAAK,KAAhB,EAAuB,OAAvB,CAA+B,UAA/B,CAArB;AAEA,gBAAM,0BAA0B,WAAW,SAAX,GAAuB,KAAK,kBAAL,EAAvD;AACA,gBAAM,qBAAqB,IAAI,aAAJ,CAAkB,eAAlB,EAAmC,SAA9D;AAEA,mBAAO,KAAK,WAAL,GAAmB,uBAAnB,GAA6C,kBAApD;AACD;AAjCM;AAJI,CAAf","sourcesContent":["/**\n * Menu position\n *\n * @mixin\n *\n * Used for calculating an automatic position (used for VSelect)\n * Will position the VMenu content properly over the VSelect\n */\n/* @vue/component */\nexport default {\n data: () => ({\n calculatedTopAuto: 0\n }),\n methods: {\n calcScrollPosition () {\n const $el = this.$refs.content\n const activeTile = $el.querySelector('.v-list__tile--active')\n const maxScrollTop = $el.scrollHeight - $el.offsetHeight\n\n return activeTile\n ? Math.min(maxScrollTop, Math.max(0, activeTile.offsetTop - $el.offsetHeight / 2 + activeTile.offsetHeight / 2))\n : $el.scrollTop\n },\n calcLeftAuto () {\n if (this.isAttached) return 0\n\n return parseInt(this.dimensions.activator.left - this.defaultOffset * 2)\n },\n calcTopAuto () {\n const $el = this.$refs.content\n const activeTile = $el.querySelector('.v-list__tile--active')\n\n if (!activeTile) {\n this.selectedIndex = null\n }\n\n if (this.offsetY || !activeTile) {\n return this.computedTop\n }\n\n this.selectedIndex = Array.from(this.tiles).indexOf(activeTile)\n\n const tileDistanceFromMenuTop = activeTile.offsetTop - this.calcScrollPosition()\n const firstTileOffsetTop = $el.querySelector('.v-list__tile').offsetTop\n\n return this.computedTop - tileDistanceFromMenuTop - firstTileOffsetTop\n }\n }\n}\n"],"sourceRoot":""}
|
||||
Reference in New Issue
Block a user