umy-ui-table 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +111 -0
- package/lib/button.js +1 -0
- package/lib/icon.js +1 -0
- package/lib/index.js +1 -0
- package/lib/locale/format.js +56 -0
- package/lib/locale/index.js +72 -0
- package/lib/locale/lang/en.js +123 -0
- package/lib/locale/lang/zh-CN.js +119 -0
- package/lib/mixins/locale.js +17 -0
- package/lib/theme-chalk/base.css +0 -0
- package/lib/theme-chalk/button.css +1 -0
- package/lib/theme-chalk/fonts/element-icons.ttf +0 -0
- package/lib/theme-chalk/fonts/element-icons.woff +0 -0
- package/lib/theme-chalk/fonts/iconfont.1785562768224.ttf +0 -0
- package/lib/theme-chalk/fonts/iconfont.1785562768224.woff +0 -0
- package/lib/theme-chalk/fonts/iconfont.1785562768224.woff2 +0 -0
- package/lib/theme-chalk/icon.css +1 -0
- package/lib/theme-chalk/index.css +1 -0
- package/lib/theme-chalk/u-table-column.css +0 -0
- package/lib/theme-chalk/u-table.css +1 -0
- package/lib/theme-chalk/ux-grid.css +1 -0
- package/lib/theme-chalk/ux-table-column.css +0 -0
- package/lib/u-table-column.js +1 -0
- package/lib/u-table.js +1 -0
- package/lib/umd/locale/en.js +139 -0
- package/lib/umd/locale/zh-CN.js +135 -0
- package/lib/umy-ui.common.js +1 -0
- package/lib/utils/svg.js +33 -0
- package/lib/utils/types.js +35 -0
- package/lib/utils/util.js +268 -0
- package/lib/ux-grid.js +1 -0
- package/lib/ux-table-column.js +1 -0
- package/package.json +117 -0
- package/packages/button/index.js +7 -0
- package/packages/button/src/button-group.vue +10 -0
- package/packages/button/src/button.vue +166 -0
- package/packages/checkbox/index.js +8 -0
- package/packages/checkbox/src/checkbox-button.vue +199 -0
- package/packages/checkbox/src/checkbox-group.vue +48 -0
- package/packages/checkbox/src/checkbox.vue +222 -0
- package/packages/checkbox-button/index.js +8 -0
- package/packages/checkbox-group/index.js +8 -0
- package/packages/icon/index.js +7 -0
- package/packages/icon/src/icon.vue +40 -0
- package/packages/input/index.js +2 -0
- package/packages/input/src/calcTextareaHeight.js +104 -0
- package/packages/input/src/input.vue +424 -0
- package/packages/option/index.js +2 -0
- package/packages/pagination/index.js +2 -0
- package/packages/pagination/src/pager.vue +163 -0
- package/packages/pagination/src/pagination.js +386 -0
- package/packages/scrollbar/index.js +8 -0
- package/packages/scrollbar/src/bar.js +92 -0
- package/packages/scrollbar/src/main.js +130 -0
- package/packages/scrollbar/src/util.js +34 -0
- package/packages/select/index.js +2 -0
- package/packages/select/src/navigation-mixin.js +54 -0
- package/packages/select/src/option-group.vue +60 -0
- package/packages/select/src/option.vue +163 -0
- package/packages/select/src/select-dropdown.vue +74 -0
- package/packages/select/src/select.vue +889 -0
- package/packages/table/index.js +8 -0
- package/packages/table/src/config.js +123 -0
- package/packages/table/src/dropdown.js +28 -0
- package/packages/table/src/filter-panel.vue +194 -0
- package/packages/table/src/layout-observer.js +68 -0
- package/packages/table/src/store/current.js +71 -0
- package/packages/table/src/store/expand.js +65 -0
- package/packages/table/src/store/helper.js +37 -0
- package/packages/table/src/store/index.js +145 -0
- package/packages/table/src/store/tree.js +208 -0
- package/packages/table/src/store/watcher.js +448 -0
- package/packages/table/src/table-body.js +493 -0
- package/packages/table/src/table-column.js +381 -0
- package/packages/table/src/table-footer.js +174 -0
- package/packages/table/src/table-header.js +537 -0
- package/packages/table/src/table-layout.js +231 -0
- package/packages/table/src/table.vue +741 -0
- package/packages/table/src/util.js +256 -0
- package/packages/tag/index.js +8 -0
- package/packages/tag/src/tag.vue +58 -0
- package/packages/tools/directives/mousewheel.js +18 -0
- package/packages/tools/directives/repeat-click.js +24 -0
- package/packages/tools/locale/format.js +46 -0
- package/packages/tools/locale/index.js +48 -0
- package/packages/tools/locale/lang/en.js +120 -0
- package/packages/tools/locale/lang/zh-CN.js +116 -0
- package/packages/tools/mixins/emitter.js +33 -0
- package/packages/tools/mixins/focus.js +9 -0
- package/packages/tools/mixins/locale.js +9 -0
- package/packages/tools/mixins/migrating.js +54 -0
- package/packages/tools/transitions/collapse-transition.js +77 -0
- package/packages/tools/utils/after-leave.js +27 -0
- package/packages/tools/utils/aria-dialog.js +90 -0
- package/packages/tools/utils/aria-utils.js +122 -0
- package/packages/tools/utils/clickoutside.js +76 -0
- package/packages/tools/utils/date-util.js +292 -0
- package/packages/tools/utils/date.js +368 -0
- package/packages/tools/utils/dom.js +227 -0
- package/packages/tools/utils/menu/aria-menubar.js +14 -0
- package/packages/tools/utils/menu/aria-menuitem.js +49 -0
- package/packages/tools/utils/menu/aria-submenu.js +59 -0
- package/packages/tools/utils/merge.js +15 -0
- package/packages/tools/utils/popper.js +1276 -0
- package/packages/tools/utils/popup/index.js +218 -0
- package/packages/tools/utils/popup/popup-manager.js +194 -0
- package/packages/tools/utils/resize-event.js +35 -0
- package/packages/tools/utils/scroll-into-view.js +27 -0
- package/packages/tools/utils/scrollbar-width.js +29 -0
- package/packages/tools/utils/shared.js +7 -0
- package/packages/tools/utils/svg.js +1 -0
- package/packages/tools/utils/types.js +28 -0
- package/packages/tools/utils/util.js +241 -0
- package/packages/tools/utils/vdom.js +5 -0
- package/packages/tools/utils/vue-popper.js +198 -0
- package/packages/tooltip/index.js +8 -0
- package/packages/tooltip/src/main.js +241 -0
- package/packages/u-table/index.js +4 -0
- package/packages/u-table/revise-el-table-mixins/index.js +10 -0
- package/packages/u-table/revise-el-table-mixins/table-extend.js +60 -0
- package/packages/u-table/revise-el-table-mixins/table.mixins.js +261 -0
- package/packages/u-table/revise-el-table-mixins/virtual-table-body-render.js +132 -0
- package/packages/u-table/src/u-table.vue +248 -0
- package/packages/u-table/u-table-mixins/index.js +483 -0
- package/packages/u-table/u-table-tree-mixins/methods.js +120 -0
- package/packages/u-table/u-table-tree-mixins/u-table-tree-mixins.js +161 -0
- package/packages/u-table-column/index.js +8 -0
- package/packages/utils/common.js +27 -0
- package/packages/ux-grid/index.js +6 -0
- package/packages/ux-grid/mixins/index.js +707 -0
- package/packages/ux-grid/src/interceptor.js +6 -0
- package/packages/ux-grid/src/ux-grid.vue +301 -0
- package/packages/ux-table-column/index.js +10 -0
- package/tools/locale/format.js +46 -0
- package/tools/locale/index.js +54 -0
- package/tools/locale/lang/en.js +120 -0
- package/tools/locale/lang/zh-CN.js +116 -0
- package/tools/mixins/locale.js +9 -0
- package/tools/utils/svg.js +1 -0
- package/tools/utils/types.js +28 -0
- package/tools/utils/util.js +241 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
function broadcast(componentName, eventName, params) {
|
|
2
|
+
this.$children.forEach(child => {
|
|
3
|
+
var name = child.$options.componentName;
|
|
4
|
+
|
|
5
|
+
if (name === componentName) {
|
|
6
|
+
child.$emit.apply(child, [eventName].concat(params));
|
|
7
|
+
} else {
|
|
8
|
+
broadcast.apply(child, [componentName, eventName].concat([params]));
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
export default {
|
|
13
|
+
methods: {
|
|
14
|
+
dispatch(componentName, eventName, params) {
|
|
15
|
+
var parent = this.$parent || this.$root;
|
|
16
|
+
var name = parent.$options.componentName;
|
|
17
|
+
|
|
18
|
+
while (parent && (!name || name !== componentName)) {
|
|
19
|
+
parent = parent.$parent;
|
|
20
|
+
|
|
21
|
+
if (parent) {
|
|
22
|
+
name = parent.$options.componentName;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (parent) {
|
|
26
|
+
parent.$emit.apply(parent, [eventName].concat(params));
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
broadcast(componentName, eventName, params) {
|
|
30
|
+
broadcast.call(this, componentName, eventName, params);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { kebabCase } from '../utils/util';
|
|
2
|
+
/**
|
|
3
|
+
* Show migrating guide in browser console.
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* import Migrating from 'umy-table/tools/mixins/migrating';
|
|
7
|
+
*
|
|
8
|
+
* mixins: [Migrating]
|
|
9
|
+
*
|
|
10
|
+
* add getMigratingConfig method for your component.
|
|
11
|
+
* getMigratingConfig() {
|
|
12
|
+
* return {
|
|
13
|
+
* props: {
|
|
14
|
+
* 'allow-no-selection': 'allow-no-selection is removed.',
|
|
15
|
+
* 'selection-mode': 'selection-mode is removed.'
|
|
16
|
+
* },
|
|
17
|
+
* events: {
|
|
18
|
+
* selectionchange: 'selectionchange is renamed to selection-change.'
|
|
19
|
+
* }
|
|
20
|
+
* };
|
|
21
|
+
* },
|
|
22
|
+
*/
|
|
23
|
+
export default {
|
|
24
|
+
mounted() {
|
|
25
|
+
if (process.env.NODE_ENV === 'production') return;
|
|
26
|
+
if (!this.$vnode) return;
|
|
27
|
+
const { props = {}, events = {} } = this.getMigratingConfig();
|
|
28
|
+
const { data, componentOptions } = this.$vnode;
|
|
29
|
+
const definedProps = data.attrs || {};
|
|
30
|
+
const definedEvents = componentOptions.listeners || {};
|
|
31
|
+
|
|
32
|
+
for (let propName in definedProps) {
|
|
33
|
+
propName = kebabCase(propName); // compatible with camel case
|
|
34
|
+
if (props[propName]) {
|
|
35
|
+
console.warn(`[Element Migrating][${this.$options.name}][Attribute]: ${props[propName]}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
for (let eventName in definedEvents) {
|
|
40
|
+
eventName = kebabCase(eventName); // compatible with camel case
|
|
41
|
+
if (events[eventName]) {
|
|
42
|
+
console.warn(`[Element Migrating][${this.$options.name}][Event]: ${events[eventName]}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
methods: {
|
|
47
|
+
getMigratingConfig() {
|
|
48
|
+
return {
|
|
49
|
+
props: {},
|
|
50
|
+
events: {}
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { addClass, removeClass } from '../utils/dom';
|
|
2
|
+
|
|
3
|
+
class Transition {
|
|
4
|
+
beforeEnter(el) {
|
|
5
|
+
addClass(el, 'collapse-transition');
|
|
6
|
+
if (!el.dataset) el.dataset = {};
|
|
7
|
+
|
|
8
|
+
el.dataset.oldPaddingTop = el.style.paddingTop;
|
|
9
|
+
el.dataset.oldPaddingBottom = el.style.paddingBottom;
|
|
10
|
+
|
|
11
|
+
el.style.height = '0';
|
|
12
|
+
el.style.paddingTop = 0;
|
|
13
|
+
el.style.paddingBottom = 0;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
enter(el) {
|
|
17
|
+
el.dataset.oldOverflow = el.style.overflow;
|
|
18
|
+
if (el.scrollHeight !== 0) {
|
|
19
|
+
el.style.height = el.scrollHeight + 'px';
|
|
20
|
+
el.style.paddingTop = el.dataset.oldPaddingTop;
|
|
21
|
+
el.style.paddingBottom = el.dataset.oldPaddingBottom;
|
|
22
|
+
} else {
|
|
23
|
+
el.style.height = '';
|
|
24
|
+
el.style.paddingTop = el.dataset.oldPaddingTop;
|
|
25
|
+
el.style.paddingBottom = el.dataset.oldPaddingBottom;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
el.style.overflow = 'hidden';
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
afterEnter(el) {
|
|
32
|
+
// for safari: remove class then reset height is necessary
|
|
33
|
+
removeClass(el, 'collapse-transition');
|
|
34
|
+
el.style.height = '';
|
|
35
|
+
el.style.overflow = el.dataset.oldOverflow;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
beforeLeave(el) {
|
|
39
|
+
if (!el.dataset) el.dataset = {};
|
|
40
|
+
el.dataset.oldPaddingTop = el.style.paddingTop;
|
|
41
|
+
el.dataset.oldPaddingBottom = el.style.paddingBottom;
|
|
42
|
+
el.dataset.oldOverflow = el.style.overflow;
|
|
43
|
+
|
|
44
|
+
el.style.height = el.scrollHeight + 'px';
|
|
45
|
+
el.style.overflow = 'hidden';
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
leave(el) {
|
|
49
|
+
if (el.scrollHeight !== 0) {
|
|
50
|
+
// for safari: add class after set height, or it will jump to zero height suddenly, weired
|
|
51
|
+
addClass(el, 'collapse-transition');
|
|
52
|
+
el.style.height = 0;
|
|
53
|
+
el.style.paddingTop = 0;
|
|
54
|
+
el.style.paddingBottom = 0;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
afterLeave(el) {
|
|
59
|
+
removeClass(el, 'collapse-transition');
|
|
60
|
+
el.style.height = '';
|
|
61
|
+
el.style.overflow = el.dataset.oldOverflow;
|
|
62
|
+
el.style.paddingTop = el.dataset.oldPaddingTop;
|
|
63
|
+
el.style.paddingBottom = el.dataset.oldPaddingBottom;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export default {
|
|
68
|
+
name: 'ElCollapseTransition',
|
|
69
|
+
functional: true,
|
|
70
|
+
render(h, { children }) {
|
|
71
|
+
const data = {
|
|
72
|
+
on: new Transition()
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
return h('transition', data, children);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bind after-leave event for vue instance. Make sure after-leave is called in any browsers.
|
|
3
|
+
*
|
|
4
|
+
* @param {Vue} instance Vue instance.
|
|
5
|
+
* @param {Function} callback callback of after-leave event
|
|
6
|
+
* @param {Number} speed the speed of transition, default value is 300ms
|
|
7
|
+
* @param {Boolean} once weather bind after-leave once. default value is false.
|
|
8
|
+
*/
|
|
9
|
+
export default function(instance, callback, speed = 300, once = false) {
|
|
10
|
+
if (!instance || !callback) throw new Error('instance & callback is required');
|
|
11
|
+
let called = false;
|
|
12
|
+
const afterLeaveCallback = function() {
|
|
13
|
+
if (called) return;
|
|
14
|
+
called = true;
|
|
15
|
+
if (callback) {
|
|
16
|
+
callback.apply(null, arguments);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
if (once) {
|
|
20
|
+
instance.$once('after-leave', afterLeaveCallback);
|
|
21
|
+
} else {
|
|
22
|
+
instance.$on('after-leave', afterLeaveCallback);
|
|
23
|
+
}
|
|
24
|
+
setTimeout(() => {
|
|
25
|
+
afterLeaveCallback();
|
|
26
|
+
}, speed + 100);
|
|
27
|
+
};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import Utils from './aria-utils';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @constructor
|
|
5
|
+
* @desc Dialog object providing modal focus management.
|
|
6
|
+
*
|
|
7
|
+
* Assumptions: The element serving as the dialog container is present in the
|
|
8
|
+
* DOM and hidden. The dialog container has role='dialog'.
|
|
9
|
+
*
|
|
10
|
+
* @param dialogId
|
|
11
|
+
* The ID of the element serving as the dialog container.
|
|
12
|
+
* @param focusAfterClosed
|
|
13
|
+
* Either the DOM node or the ID of the DOM node to focus when the
|
|
14
|
+
* dialog closes.
|
|
15
|
+
* @param focusFirst
|
|
16
|
+
* Optional parameter containing either the DOM node or the ID of the
|
|
17
|
+
* DOM node to focus when the dialog opens. If not specified, the
|
|
18
|
+
* first focusable element in the dialog will receive focus.
|
|
19
|
+
*/
|
|
20
|
+
var aria = aria || {};
|
|
21
|
+
var tabEvent;
|
|
22
|
+
|
|
23
|
+
aria.Dialog = function(dialog, focusAfterClosed, focusFirst) {
|
|
24
|
+
this.dialogNode = dialog;
|
|
25
|
+
if (this.dialogNode === null || this.dialogNode.getAttribute('role') !== 'dialog') {
|
|
26
|
+
throw new Error('Dialog() requires a DOM element with ARIA role of dialog.');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (typeof focusAfterClosed === 'string') {
|
|
30
|
+
this.focusAfterClosed = document.getElementById(focusAfterClosed);
|
|
31
|
+
} else if (typeof focusAfterClosed === 'object') {
|
|
32
|
+
this.focusAfterClosed = focusAfterClosed;
|
|
33
|
+
} else {
|
|
34
|
+
this.focusAfterClosed = null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (typeof focusFirst === 'string') {
|
|
38
|
+
this.focusFirst = document.getElementById(focusFirst);
|
|
39
|
+
} else if (typeof focusFirst === 'object') {
|
|
40
|
+
this.focusFirst = focusFirst;
|
|
41
|
+
} else {
|
|
42
|
+
this.focusFirst = null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (this.focusFirst) {
|
|
46
|
+
this.focusFirst.focus();
|
|
47
|
+
} else {
|
|
48
|
+
Utils.focusFirstDescendant(this.dialogNode);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
this.lastFocus = document.activeElement;
|
|
52
|
+
tabEvent = (e) => {
|
|
53
|
+
this.trapFocus(e);
|
|
54
|
+
};
|
|
55
|
+
this.addListeners();
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
aria.Dialog.prototype.addListeners = function() {
|
|
59
|
+
document.addEventListener('focus', tabEvent, true);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
aria.Dialog.prototype.removeListeners = function() {
|
|
63
|
+
document.removeEventListener('focus', tabEvent, true);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
aria.Dialog.prototype.closeDialog = function() {
|
|
67
|
+
this.removeListeners();
|
|
68
|
+
if (this.focusAfterClosed) {
|
|
69
|
+
setTimeout(() => {
|
|
70
|
+
this.focusAfterClosed.focus();
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
aria.Dialog.prototype.trapFocus = function(event) {
|
|
76
|
+
if (Utils.IgnoreUtilFocusChanges) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (this.dialogNode.contains(event.target)) {
|
|
80
|
+
this.lastFocus = event.target;
|
|
81
|
+
} else {
|
|
82
|
+
Utils.focusFirstDescendant(this.dialogNode);
|
|
83
|
+
if (this.lastFocus === document.activeElement) {
|
|
84
|
+
Utils.focusLastDescendant(this.dialogNode);
|
|
85
|
+
}
|
|
86
|
+
this.lastFocus = document.activeElement;
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export default aria.Dialog;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
var aria = aria || {};
|
|
2
|
+
|
|
3
|
+
aria.Utils = aria.Utils || {};
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @desc Set focus on descendant nodes until the first focusable element is
|
|
7
|
+
* found.
|
|
8
|
+
* @param element
|
|
9
|
+
* DOM node for which to find the first focusable descendant.
|
|
10
|
+
* @returns
|
|
11
|
+
* true if a focusable element is found and focus is set.
|
|
12
|
+
*/
|
|
13
|
+
aria.Utils.focusFirstDescendant = function(element) {
|
|
14
|
+
for (var i = 0; i < element.childNodes.length; i++) {
|
|
15
|
+
var child = element.childNodes[i];
|
|
16
|
+
if (aria.Utils.attemptFocus(child) || aria.Utils.focusFirstDescendant(child)) {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return false;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @desc Find the last descendant node that is focusable.
|
|
25
|
+
* @param element
|
|
26
|
+
* DOM node for which to find the last focusable descendant.
|
|
27
|
+
* @returns
|
|
28
|
+
* true if a focusable element is found and focus is set.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
aria.Utils.focusLastDescendant = function(element) {
|
|
32
|
+
for (var i = element.childNodes.length - 1; i >= 0; i--) {
|
|
33
|
+
var child = element.childNodes[i];
|
|
34
|
+
if (aria.Utils.attemptFocus(child) || aria.Utils.focusLastDescendant(child)) {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return false;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @desc Set Attempt to set focus on the current node.
|
|
43
|
+
* @param element
|
|
44
|
+
* The node to attempt to focus on.
|
|
45
|
+
* @returns
|
|
46
|
+
* true if element is focused.
|
|
47
|
+
*/
|
|
48
|
+
aria.Utils.attemptFocus = function(element) {
|
|
49
|
+
if (!aria.Utils.isFocusable(element)) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
aria.Utils.IgnoreUtilFocusChanges = true;
|
|
53
|
+
try {
|
|
54
|
+
element.focus();
|
|
55
|
+
} catch (e) {
|
|
56
|
+
}
|
|
57
|
+
aria.Utils.IgnoreUtilFocusChanges = false;
|
|
58
|
+
return (document.activeElement === element);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
aria.Utils.isFocusable = function(element) {
|
|
62
|
+
if (element.tabIndex > 0 || (element.tabIndex === 0 && element.getAttribute('tabIndex') !== null)) {
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (element.disabled) {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
switch (element.nodeName) {
|
|
71
|
+
case 'A':
|
|
72
|
+
return !!element.href && element.rel !== 'ignore';
|
|
73
|
+
case 'INPUT':
|
|
74
|
+
return element.type !== 'hidden' && element.type !== 'file';
|
|
75
|
+
case 'BUTTON':
|
|
76
|
+
case 'SELECT':
|
|
77
|
+
case 'TEXTAREA':
|
|
78
|
+
return true;
|
|
79
|
+
default:
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* 触发一个事件
|
|
86
|
+
* mouseenter, mouseleave, mouseover, keyup, change, click 等
|
|
87
|
+
* @param {Element} elm
|
|
88
|
+
* @param {String} name
|
|
89
|
+
* @param {*} opts
|
|
90
|
+
*/
|
|
91
|
+
aria.Utils.triggerEvent = function(elm, name, ...opts) {
|
|
92
|
+
let eventName;
|
|
93
|
+
|
|
94
|
+
if (/^mouse|click/.test(name)) {
|
|
95
|
+
eventName = 'MouseEvents';
|
|
96
|
+
} else if (/^key/.test(name)) {
|
|
97
|
+
eventName = 'KeyboardEvent';
|
|
98
|
+
} else {
|
|
99
|
+
eventName = 'HTMLEvents';
|
|
100
|
+
}
|
|
101
|
+
const evt = document.createEvent(eventName);
|
|
102
|
+
|
|
103
|
+
evt.initEvent(name, ...opts);
|
|
104
|
+
elm.dispatchEvent
|
|
105
|
+
? elm.dispatchEvent(evt)
|
|
106
|
+
: elm.fireEvent('on' + name, evt);
|
|
107
|
+
|
|
108
|
+
return elm;
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
aria.Utils.keys = {
|
|
112
|
+
tab: 9,
|
|
113
|
+
enter: 13,
|
|
114
|
+
space: 32,
|
|
115
|
+
left: 37,
|
|
116
|
+
up: 38,
|
|
117
|
+
right: 39,
|
|
118
|
+
down: 40,
|
|
119
|
+
esc: 27
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
export default aria.Utils;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import Vue from 'vue';
|
|
2
|
+
import { on } from './dom';
|
|
3
|
+
|
|
4
|
+
const nodeList = [];
|
|
5
|
+
const ctx = '@@clickoutsideContext';
|
|
6
|
+
|
|
7
|
+
let startClick;
|
|
8
|
+
let seed = 0;
|
|
9
|
+
|
|
10
|
+
!Vue.prototype.$isServer && on(document, 'mousedown', e => (startClick = e));
|
|
11
|
+
|
|
12
|
+
!Vue.prototype.$isServer && on(document, 'mouseup', e => {
|
|
13
|
+
nodeList.forEach(node => node[ctx].documentHandler(e, startClick));
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
function createDocumentHandler(el, binding, vnode) {
|
|
17
|
+
return function(mouseup = {}, mousedown = {}) {
|
|
18
|
+
if (!vnode ||
|
|
19
|
+
!vnode.context ||
|
|
20
|
+
!mouseup.target ||
|
|
21
|
+
!mousedown.target ||
|
|
22
|
+
el.contains(mouseup.target) ||
|
|
23
|
+
el.contains(mousedown.target) ||
|
|
24
|
+
el === mouseup.target ||
|
|
25
|
+
(vnode.context.popperElm &&
|
|
26
|
+
(vnode.context.popperElm.contains(mouseup.target) ||
|
|
27
|
+
vnode.context.popperElm.contains(mousedown.target)))) return;
|
|
28
|
+
|
|
29
|
+
if (binding.expression &&
|
|
30
|
+
el[ctx].methodName &&
|
|
31
|
+
vnode.context[el[ctx].methodName]) {
|
|
32
|
+
vnode.context[el[ctx].methodName]();
|
|
33
|
+
} else {
|
|
34
|
+
el[ctx].bindingFn && el[ctx].bindingFn();
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* v-clickoutside
|
|
41
|
+
* @desc 点击元素外面才会触发的事件
|
|
42
|
+
* @example
|
|
43
|
+
* ```vue
|
|
44
|
+
* <div v-element-clickoutside="handleClose">
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export default {
|
|
48
|
+
bind(el, binding, vnode) {
|
|
49
|
+
nodeList.push(el);
|
|
50
|
+
const id = seed++;
|
|
51
|
+
el[ctx] = {
|
|
52
|
+
id,
|
|
53
|
+
documentHandler: createDocumentHandler(el, binding, vnode),
|
|
54
|
+
methodName: binding.expression,
|
|
55
|
+
bindingFn: binding.value
|
|
56
|
+
};
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
update(el, binding, vnode) {
|
|
60
|
+
el[ctx].documentHandler = createDocumentHandler(el, binding, vnode);
|
|
61
|
+
el[ctx].methodName = binding.expression;
|
|
62
|
+
el[ctx].bindingFn = binding.value;
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
unbind(el) {
|
|
66
|
+
let len = nodeList.length;
|
|
67
|
+
|
|
68
|
+
for (let i = 0; i < len; i++) {
|
|
69
|
+
if (nodeList[i][ctx].id === el[ctx].id) {
|
|
70
|
+
nodeList.splice(i, 1);
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
delete el[ctx];
|
|
75
|
+
}
|
|
76
|
+
};
|