@gitlab/ui 126.3.4 → 126.4.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/dist/components/base/alert/alert.js +9 -0
- package/dist/components/base/breadcrumb/breadcrumb.js +3 -0
- package/dist/components/base/breadcrumb/breadcrumb_item.js +15 -0
- package/dist/components/base/datepicker/datepicker.js +54 -0
- package/dist/components/base/daterange_picker/daterange_picker.js +70 -1
- package/dist/components/base/filtered_search/filtered_search.js +1 -1
- package/dist/components/base/form/form_input_group/form_input_group.js +9 -1
- package/dist/components/base/path/data.js +1 -1
- package/dist/components/base/search_box_by_click/search_box_by_click.js +9 -1
- package/dist/components/dashboards/dashboard_panel/dashboard_panel.js +10 -2
- package/dist/directives/resize_observer/resize_observer.js +10 -3
- package/dist/index.css.map +1 -1
- package/dist/tailwind.css +1 -1
- package/dist/tailwind.css.map +1 -1
- package/dist/vendor/bootstrap-vue/src/components/modal/modal.js +7 -2
- package/dist/vendor/bootstrap-vue/src/components/table/helpers/mixin-filtering.js +8 -0
- package/dist/vendor/bootstrap-vue/src/components/table/helpers/mixin-items.js +4 -0
- package/dist/vendor/bootstrap-vue/src/components/table/helpers/mixin-provider.js +8 -4
- package/dist/vendor/bootstrap-vue/src/components/table/helpers/mixin-selectable.js +3 -19
- package/dist/vendor/bootstrap-vue/src/components/table/helpers/mixin-sorting.js +1 -16
- package/dist/vendor/bootstrap-vue/src/components/table/helpers/mixin-tbody.js +8 -2
- package/dist/vendor/bootstrap-vue/src/components/table/helpers/mixin-thead.js +4 -0
- package/dist/vendor/bootstrap-vue/src/components/toast/helpers/bv-toast.js +15 -7
- package/dist/vendor/bootstrap-vue/src/components/tooltip/helpers/bv-popper.js +15 -13
- package/dist/vendor/bootstrap-vue/src/components/tooltip/helpers/bv-tooltip.js +24 -21
- package/dist/vendor/bootstrap-vue/src/components/tooltip/tooltip.js +10 -9
- package/dist/vendor/bootstrap-vue/src/components/transition/bv-transition.js +3 -0
- package/dist/vendor/bootstrap-vue/src/components/transporter/transporter.js +29 -21
- package/dist/vendor/bootstrap-vue/src/constants/events.js +1 -5
- package/dist/vendor/bootstrap-vue/src/directives/tooltip/tooltip.js +15 -13
- package/dist/vendor/bootstrap-vue/src/directives/visible/visible.js +15 -16
- package/dist/vendor/bootstrap-vue/src/mixins/attrs.js +1 -18
- package/dist/vendor/bootstrap-vue/src/mixins/dropdown.js +8 -3
- package/dist/vendor/bootstrap-vue/src/mixins/has-listener.js +1 -1
- package/dist/vendor/bootstrap-vue/src/mixins/listeners.js +13 -12
- package/dist/vendor/bootstrap-vue/src/utils/cache.js +35 -13
- package/dist/vendor/bootstrap-vue/src/utils/config-set.js +16 -11
- package/dist/vendor/bootstrap-vue/src/utils/config.js +4 -10
- package/dist/vendor/bootstrap-vue/src/utils/create-new-child-component.js +102 -3
- package/dist/vendor/bootstrap-vue/src/utils/element-to-vue-instance-registry.js +3 -9
- package/dist/vendor/bootstrap-vue/src/utils/get-instance-from-directive.js +1 -3
- package/dist/vendor/bootstrap-vue/src/utils/on-instance-destroy.js +22 -0
- package/dist/vendor/bootstrap-vue/src/utils/plugins.js +2 -21
- package/dist/vendor/bootstrap-vue/src/utils/router.js +15 -1
- package/dist/vendor/bootstrap-vue/src/utils/safe-vue-instance.js +1 -1
- package/dist/vendor/bootstrap-vue/src/vue.js +16 -81
- package/package.json +6 -6
- package/src/components/base/alert/alert.vue +9 -0
- package/src/components/base/breadcrumb/breadcrumb.vue +3 -0
- package/src/components/base/breadcrumb/breadcrumb_item.vue +15 -0
- package/src/components/base/datepicker/datepicker.vue +54 -0
- package/src/components/base/daterange_picker/daterange_picker.vue +70 -1
- package/src/components/base/filtered_search/filtered_search.vue +1 -1
- package/src/components/base/form/form_input_group/form_input_group.vue +9 -1
- package/src/components/base/path/data.js +1 -1
- package/src/components/base/search_box_by_click/search_box_by_click.vue +9 -0
- package/src/components/dashboards/dashboard_panel/dashboard_panel.vue +27 -9
- package/src/directives/resize_observer/resize_observer.js +6 -0
- package/src/vendor/bootstrap-vue/src/components/modal/modal.js +6 -1
- package/src/vendor/bootstrap-vue/src/components/table/helpers/mixin-filtering.js +8 -0
- package/src/vendor/bootstrap-vue/src/components/table/helpers/mixin-items.js +4 -0
- package/src/vendor/bootstrap-vue/src/components/table/helpers/mixin-provider.js +9 -4
- package/src/vendor/bootstrap-vue/src/components/table/helpers/mixin-selectable.js +3 -24
- package/src/vendor/bootstrap-vue/src/components/table/helpers/mixin-sorting.js +1 -20
- package/src/vendor/bootstrap-vue/src/components/table/helpers/mixin-tbody.js +8 -2
- package/src/vendor/bootstrap-vue/src/components/table/helpers/mixin-thead.js +4 -0
- package/src/vendor/bootstrap-vue/src/components/toast/helpers/bv-toast.js +15 -13
- package/src/vendor/bootstrap-vue/src/components/tooltip/helpers/bv-popper.js +14 -13
- package/src/vendor/bootstrap-vue/src/components/tooltip/helpers/bv-tooltip.js +16 -23
- package/src/vendor/bootstrap-vue/src/components/tooltip/tooltip.js +10 -9
- package/src/vendor/bootstrap-vue/src/components/transition/bv-transition.js +4 -0
- package/src/vendor/bootstrap-vue/src/components/transporter/transporter.js +36 -26
- package/src/vendor/bootstrap-vue/src/constants/events.js +0 -5
- package/src/vendor/bootstrap-vue/src/directives/tooltip/tooltip.js +17 -13
- package/src/vendor/bootstrap-vue/src/directives/visible/visible.js +13 -9
- package/src/vendor/bootstrap-vue/src/mixins/attrs.js +1 -17
- package/src/vendor/bootstrap-vue/src/mixins/dropdown.js +8 -3
- package/src/vendor/bootstrap-vue/src/mixins/has-listener.js +1 -1
- package/src/vendor/bootstrap-vue/src/mixins/listeners.js +14 -14
- package/src/vendor/bootstrap-vue/src/utils/cache.js +27 -7
- package/src/vendor/bootstrap-vue/src/utils/config-set.js +16 -11
- package/src/vendor/bootstrap-vue/src/utils/config.js +4 -10
- package/src/vendor/bootstrap-vue/src/utils/create-new-child-component.js +85 -2
- package/src/vendor/bootstrap-vue/src/utils/element-to-vue-instance-registry.js +3 -10
- package/src/vendor/bootstrap-vue/src/utils/get-instance-from-directive.js +1 -4
- package/src/vendor/bootstrap-vue/src/utils/on-instance-destroy.js +21 -0
- package/src/vendor/bootstrap-vue/src/utils/plugins.js +1 -26
- package/src/vendor/bootstrap-vue/src/utils/router.js +13 -1
- package/src/vendor/bootstrap-vue/src/utils/safe-vue-instance.js +1 -1
- package/src/vendor/bootstrap-vue/src/vue.js +11 -98
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { extend, isVue3
|
|
1
|
+
import { extend, isVue3 } from '../../vue';
|
|
2
2
|
import { NAME_TRANSPORTER_TARGET, NAME_TRANSPORTER } from '../../constants/components';
|
|
3
3
|
import { IS_BROWSER } from '../../constants/env';
|
|
4
4
|
import { PROP_TYPE_ARRAY_FUNCTION, PROP_TYPE_STRING, PROP_TYPE_BOOLEAN } from '../../constants/props';
|
|
@@ -76,7 +76,7 @@ const props = {
|
|
|
76
76
|
// --- Main component ---
|
|
77
77
|
|
|
78
78
|
// @vue/component
|
|
79
|
-
const
|
|
79
|
+
const BVTransporter = /*#__PURE__*/extend({
|
|
80
80
|
name: NAME_TRANSPORTER,
|
|
81
81
|
mixins: [normalizeSlotMixin],
|
|
82
82
|
props,
|
|
@@ -84,28 +84,37 @@ const BVTransporterVue2 = /*#__PURE__*/extend({
|
|
|
84
84
|
disabled: {
|
|
85
85
|
immediate: true,
|
|
86
86
|
handler(disabled) {
|
|
87
|
+
// Vue 2 only: manage manual portaling
|
|
88
|
+
if (isVue3(this)) return;
|
|
87
89
|
disabled ? this.unmountTarget() : this.$nextTick(this.mountTarget);
|
|
88
90
|
}
|
|
89
91
|
}
|
|
90
92
|
},
|
|
91
93
|
created() {
|
|
92
|
-
//
|
|
94
|
+
// Vue 2 only: create private non-reactive props
|
|
95
|
+
if (isVue3(this)) return;
|
|
93
96
|
this.$_defaultFn = null;
|
|
94
97
|
this.$_target = null;
|
|
95
98
|
},
|
|
96
99
|
beforeMount() {
|
|
100
|
+
// Vue 2 only
|
|
101
|
+
if (isVue3(this)) return;
|
|
97
102
|
this.mountTarget();
|
|
98
103
|
},
|
|
99
104
|
updated() {
|
|
105
|
+
// Vue 2 only
|
|
100
106
|
// We need to make sure that all children have completed updating
|
|
101
107
|
// before rendering in the target
|
|
102
108
|
// `vue-simple-portal` has the this in a `$nextTick()`,
|
|
103
109
|
// while `portal-vue` doesn't
|
|
104
110
|
// Just trying to see if the `$nextTick()` delay is required or not
|
|
105
111
|
// Since all slots in Vue 2.6.x are always functions
|
|
112
|
+
if (isVue3(this)) return;
|
|
106
113
|
this.updateTarget();
|
|
107
114
|
},
|
|
108
115
|
beforeDestroy() {
|
|
116
|
+
// Vue 2 only
|
|
117
|
+
if (isVue3(this)) return;
|
|
109
118
|
this.unmountTarget();
|
|
110
119
|
this.$_defaultFn = null;
|
|
111
120
|
},
|
|
@@ -166,32 +175,31 @@ const BVTransporterVue2 = /*#__PURE__*/extend({
|
|
|
166
175
|
}
|
|
167
176
|
},
|
|
168
177
|
render(h) {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
178
|
+
if (isVue3(this)) {
|
|
179
|
+
// Vue 3: use native Teleport
|
|
180
|
+
if (this.disabled) {
|
|
181
|
+
const $nodes = concat(this.normalizeSlot()).filter(identity);
|
|
182
|
+
if ($nodes.length > 0) {
|
|
183
|
+
return $nodes[0];
|
|
184
|
+
}
|
|
174
185
|
}
|
|
186
|
+
const {
|
|
187
|
+
Teleport
|
|
188
|
+
} = this.$.appContext.config.globalProperties.constructor;
|
|
189
|
+
return h(Teleport, {
|
|
190
|
+
to: this.container
|
|
191
|
+
}, this.normalizeSlot());
|
|
175
192
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
});
|
|
179
|
-
const BVTransporterVue3 = /*#__PURE__*/extend({
|
|
180
|
-
name: NAME_TRANSPORTER,
|
|
181
|
-
mixins: [normalizeSlotMixin],
|
|
182
|
-
props,
|
|
183
|
-
render(h) {
|
|
193
|
+
|
|
194
|
+
// Vue 2: this component has no root element, so only a single VNode is allowed
|
|
184
195
|
if (this.disabled) {
|
|
185
196
|
const $nodes = concat(this.normalizeSlot()).filter(identity);
|
|
186
|
-
if ($nodes.length > 0) {
|
|
197
|
+
if ($nodes.length > 0 && !$nodes[0].text) {
|
|
187
198
|
return $nodes[0];
|
|
188
199
|
}
|
|
189
200
|
}
|
|
190
|
-
return h(
|
|
191
|
-
to: this.container
|
|
192
|
-
}, this.normalizeSlot());
|
|
201
|
+
return h();
|
|
193
202
|
}
|
|
194
203
|
});
|
|
195
|
-
const BVTransporter = isVue3 ? BVTransporterVue3 : BVTransporterVue2;
|
|
196
204
|
|
|
197
205
|
export { BVTransporter, props };
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { isVue3 } from '../vue';
|
|
2
|
-
|
|
3
1
|
const EVENT_NAME_ACTIVATE_TAB = 'activate-tab';
|
|
4
2
|
const EVENT_NAME_BLUR = 'blur';
|
|
5
3
|
const EVENT_NAME_CANCEL = 'cancel';
|
|
@@ -44,8 +42,6 @@ const EVENT_NAME_SHOWN = 'shown';
|
|
|
44
42
|
const EVENT_NAME_SORT_CHANGED = 'sort-changed';
|
|
45
43
|
const EVENT_NAME_TOGGLE = 'toggle';
|
|
46
44
|
const EVENT_NAME_UPDATE = 'update';
|
|
47
|
-
const HOOK_EVENT_NAME_BEFORE_DESTROY = isVue3 ? 'vnodeBeforeUnmount' : 'hook:beforeDestroy';
|
|
48
|
-
const HOOK_EVENT_NAME_DESTROYED = isVue3 ? 'vNodeUnmounted' : 'hook:destroyed';
|
|
49
45
|
const MODEL_EVENT_NAME_PREFIX = 'update:';
|
|
50
46
|
const ROOT_EVENT_NAME_PREFIX = 'bv';
|
|
51
47
|
const ROOT_EVENT_NAME_SEPARATOR = '::';
|
|
@@ -57,4 +53,4 @@ const EVENT_OPTIONS_NO_CAPTURE = {
|
|
|
57
53
|
capture: false
|
|
58
54
|
};
|
|
59
55
|
|
|
60
|
-
export { EVENT_NAME_ACTIVATE_TAB, EVENT_NAME_BLUR, EVENT_NAME_CANCEL, EVENT_NAME_CHANGE, EVENT_NAME_CHANGED, EVENT_NAME_CLICK, EVENT_NAME_CLOSE, EVENT_NAME_CONTEXT, EVENT_NAME_CONTEXT_CHANGED, EVENT_NAME_DESTROYED, EVENT_NAME_DISABLE, EVENT_NAME_DISABLED, EVENT_NAME_ENABLE, EVENT_NAME_ENABLED, EVENT_NAME_FILTERED, EVENT_NAME_FIRST, EVENT_NAME_FOCUS, EVENT_NAME_FOCUSIN, EVENT_NAME_FOCUSOUT, EVENT_NAME_HEAD_CLICKED, EVENT_NAME_HIDDEN, EVENT_NAME_HIDE, EVENT_NAME_INPUT, EVENT_NAME_LAST, EVENT_NAME_MOUSEENTER, EVENT_NAME_MOUSELEAVE, EVENT_NAME_NEXT, EVENT_NAME_OK, EVENT_NAME_OPEN, EVENT_NAME_PREV, EVENT_NAME_REFRESH, EVENT_NAME_REFRESHED, EVENT_NAME_ROW_CLICKED, EVENT_NAME_ROW_CONTEXTMENU, EVENT_NAME_ROW_DBLCLICKED, EVENT_NAME_ROW_HOVERED, EVENT_NAME_ROW_MIDDLE_CLICKED, EVENT_NAME_ROW_SELECTED, EVENT_NAME_ROW_UNHOVERED, EVENT_NAME_SHOW, EVENT_NAME_SHOWN, EVENT_NAME_SORT_CHANGED, EVENT_NAME_TOGGLE, EVENT_NAME_UPDATE, EVENT_OPTIONS_NO_CAPTURE, EVENT_OPTIONS_PASSIVE,
|
|
56
|
+
export { EVENT_NAME_ACTIVATE_TAB, EVENT_NAME_BLUR, EVENT_NAME_CANCEL, EVENT_NAME_CHANGE, EVENT_NAME_CHANGED, EVENT_NAME_CLICK, EVENT_NAME_CLOSE, EVENT_NAME_CONTEXT, EVENT_NAME_CONTEXT_CHANGED, EVENT_NAME_DESTROYED, EVENT_NAME_DISABLE, EVENT_NAME_DISABLED, EVENT_NAME_ENABLE, EVENT_NAME_ENABLED, EVENT_NAME_FILTERED, EVENT_NAME_FIRST, EVENT_NAME_FOCUS, EVENT_NAME_FOCUSIN, EVENT_NAME_FOCUSOUT, EVENT_NAME_HEAD_CLICKED, EVENT_NAME_HIDDEN, EVENT_NAME_HIDE, EVENT_NAME_INPUT, EVENT_NAME_LAST, EVENT_NAME_MOUSEENTER, EVENT_NAME_MOUSELEAVE, EVENT_NAME_NEXT, EVENT_NAME_OK, EVENT_NAME_OPEN, EVENT_NAME_PREV, EVENT_NAME_REFRESH, EVENT_NAME_REFRESHED, EVENT_NAME_ROW_CLICKED, EVENT_NAME_ROW_CONTEXTMENU, EVENT_NAME_ROW_DBLCLICKED, EVENT_NAME_ROW_HOVERED, EVENT_NAME_ROW_MIDDLE_CLICKED, EVENT_NAME_ROW_SELECTED, EVENT_NAME_ROW_UNHOVERED, EVENT_NAME_SHOW, EVENT_NAME_SHOWN, EVENT_NAME_SORT_CHANGED, EVENT_NAME_TOGGLE, EVENT_NAME_UPDATE, EVENT_OPTIONS_NO_CAPTURE, EVENT_OPTIONS_PASSIVE, MODEL_EVENT_NAME_PREFIX, ROOT_EVENT_NAME_PREFIX, ROOT_EVENT_NAME_SEPARATOR };
|
|
@@ -2,7 +2,7 @@ import { NAME_TOOLTIP } from '../../constants/components';
|
|
|
2
2
|
import { IS_BROWSER } from '../../constants/env';
|
|
3
3
|
import { EVENT_NAME_SHOW } from '../../constants/events';
|
|
4
4
|
import { concat } from '../../utils/array';
|
|
5
|
-
import {
|
|
5
|
+
import { isVue3 } from '../../vue';
|
|
6
6
|
import { getComponentConfig } from '../../utils/config';
|
|
7
7
|
import { getScopeId } from '../../utils/get-scope-id';
|
|
8
8
|
import { identity } from '../../utils/identity';
|
|
@@ -11,7 +11,7 @@ import { isFunction, isString, isNumber, isPlainObject, isUndefined, isUndefined
|
|
|
11
11
|
import { looseEqual } from '../../utils/loose-equal';
|
|
12
12
|
import { toInteger } from '../../utils/number';
|
|
13
13
|
import { keys } from '../../utils/object';
|
|
14
|
-
import { createNewChildComponent } from '../../utils/create-new-child-component';
|
|
14
|
+
import { createNewChildComponent, eventProp } from '../../utils/create-new-child-component';
|
|
15
15
|
import { BVTooltip } from '../../components/tooltip/helpers/bv-tooltip';
|
|
16
16
|
|
|
17
17
|
// Key which we use to store tooltip object on element
|
|
@@ -84,7 +84,7 @@ const parseBindings = (bindings, vnode) => /* istanbul ignore next: not easy to
|
|
|
84
84
|
// If title is not provided, try title attribute
|
|
85
85
|
if (isUndefined(config.title)) {
|
|
86
86
|
// Try attribute
|
|
87
|
-
const attrs = isVue3 ? vnode.props : (vnode.data || {}).attrs;
|
|
87
|
+
const attrs = isVue3(getInstanceFromDirective(vnode, bindings)) ? vnode.props : (vnode.data || {}).attrs;
|
|
88
88
|
config.title = attrs && !isUndefinedOrNull(attrs.title) ? attrs.title : undefined;
|
|
89
89
|
}
|
|
90
90
|
|
|
@@ -187,17 +187,19 @@ const applyTooltip = (el, bindings, vnode) => {
|
|
|
187
187
|
const parent = getInstanceFromDirective(vnode, bindings);
|
|
188
188
|
el[BV_TOOLTIP] = createNewChildComponent(parent, BVTooltip, {
|
|
189
189
|
// Add the parent's scoped style attribute data
|
|
190
|
-
_scopeId: getScopeId(parent, undefined)
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
190
|
+
_scopeId: getScopeId(parent, undefined),
|
|
191
|
+
propsData: {
|
|
192
|
+
[eventProp(EVENT_NAME_SHOW)]: () => /* istanbul ignore next: for now */{
|
|
193
|
+
// Before showing the tooltip, we update the title if it is a function
|
|
194
|
+
if (isFunction(config.title)) {
|
|
195
|
+
el[BV_TOOLTIP].updateData({
|
|
196
|
+
title: config.title(el)
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
}
|
|
199
200
|
}
|
|
200
201
|
});
|
|
202
|
+
el[BV_TOOLTIP].__bv_prev_data__ = {};
|
|
201
203
|
}
|
|
202
204
|
const data = {
|
|
203
205
|
title: config.title,
|
|
@@ -252,7 +254,7 @@ const VBTooltip = {
|
|
|
252
254
|
// waits until the containing component and children have finished updating
|
|
253
255
|
componentUpdated(el, bindings, vnode) {
|
|
254
256
|
// Performed in a `$nextTick()` to prevent render update loops
|
|
255
|
-
nextTick(() => {
|
|
257
|
+
getInstanceFromDirective(vnode, bindings).$nextTick(() => {
|
|
256
258
|
applyTooltip(el, bindings, vnode);
|
|
257
259
|
});
|
|
258
260
|
},
|
|
@@ -3,7 +3,7 @@ import { requestAF } from '../../utils/dom';
|
|
|
3
3
|
import { isFunction } from '../../utils/inspect';
|
|
4
4
|
import { looseEqual } from '../../utils/loose-equal';
|
|
5
5
|
import { keys, clone } from '../../utils/object';
|
|
6
|
-
import {
|
|
6
|
+
import { getInstanceFromDirective } from '../../utils/get-instance-from-directive';
|
|
7
7
|
|
|
8
8
|
// v-b-visible
|
|
9
9
|
// Private visibility check directive
|
|
@@ -40,7 +40,7 @@ import { nextTick } from '../../vue';
|
|
|
40
40
|
|
|
41
41
|
const OBSERVER_PROP_NAME = '__bv__visibility_observer';
|
|
42
42
|
class VisibilityObserver {
|
|
43
|
-
constructor(el, options) {
|
|
43
|
+
constructor(el, options, instance) {
|
|
44
44
|
this.el = el;
|
|
45
45
|
this.callback = options.callback;
|
|
46
46
|
this.margin = options.margin || 0;
|
|
@@ -48,6 +48,7 @@ class VisibilityObserver {
|
|
|
48
48
|
this.observer = null;
|
|
49
49
|
this.visible = undefined;
|
|
50
50
|
this.doneOnce = false;
|
|
51
|
+
this.instance = instance;
|
|
51
52
|
// Create the observer instance (if possible)
|
|
52
53
|
this.createObserver();
|
|
53
54
|
}
|
|
@@ -86,7 +87,7 @@ class VisibilityObserver {
|
|
|
86
87
|
|
|
87
88
|
// Start observing in a `$nextTick()` (to allow DOM to complete rendering)
|
|
88
89
|
/* istanbul ignore next: IntersectionObserver not supported in JSDOM */
|
|
89
|
-
nextTick(() => {
|
|
90
|
+
this.instance.$nextTick(() => {
|
|
90
91
|
requestAF(() => {
|
|
91
92
|
// Placed in an `if` just in case we were destroyed before
|
|
92
93
|
// this `requestAnimationFrame` runs
|
|
@@ -123,11 +124,11 @@ const destroy = el => {
|
|
|
123
124
|
}
|
|
124
125
|
delete el[OBSERVER_PROP_NAME];
|
|
125
126
|
};
|
|
126
|
-
const bind = (el,
|
|
127
|
-
|
|
127
|
+
const bind = (el, bindings, vnode) => {
|
|
128
|
+
const {
|
|
128
129
|
value,
|
|
129
130
|
modifiers
|
|
130
|
-
} =
|
|
131
|
+
} = bindings;
|
|
131
132
|
// `value` is the callback function
|
|
132
133
|
const options = {
|
|
133
134
|
margin: '0px',
|
|
@@ -146,29 +147,27 @@ const bind = (el, _ref) => {
|
|
|
146
147
|
// Destroy any previous observer
|
|
147
148
|
destroy(el);
|
|
148
149
|
// Create new observer
|
|
149
|
-
|
|
150
|
+
const instance = getInstanceFromDirective(vnode, bindings);
|
|
151
|
+
el[OBSERVER_PROP_NAME] = new VisibilityObserver(el, options, instance);
|
|
150
152
|
// Store the current modifiers on the object (cloned)
|
|
151
153
|
el[OBSERVER_PROP_NAME]._prevModifiers = clone(modifiers);
|
|
152
154
|
};
|
|
153
155
|
|
|
154
156
|
// When the directive options may have been updated (or element)
|
|
155
|
-
const componentUpdated = (el,
|
|
156
|
-
|
|
157
|
+
const componentUpdated = (el, bindings, vnode) => {
|
|
158
|
+
const {
|
|
157
159
|
value,
|
|
158
160
|
oldValue,
|
|
159
161
|
modifiers
|
|
160
|
-
} =
|
|
162
|
+
} = bindings;
|
|
161
163
|
// Compare value/oldValue and modifiers to see if anything has changed
|
|
162
164
|
// and if so, destroy old observer and create new observer
|
|
163
165
|
/* istanbul ignore next */
|
|
164
|
-
|
|
166
|
+
const clonedModifiers = clone(modifiers);
|
|
165
167
|
/* istanbul ignore next */
|
|
166
|
-
if (el && (value !== oldValue || !el[OBSERVER_PROP_NAME] || !looseEqual(
|
|
168
|
+
if (el && (value !== oldValue || !el[OBSERVER_PROP_NAME] || !looseEqual(clonedModifiers, el[OBSERVER_PROP_NAME]._prevModifiers))) {
|
|
167
169
|
// Re-bind on element
|
|
168
|
-
bind(el,
|
|
169
|
-
value,
|
|
170
|
-
modifiers
|
|
171
|
-
});
|
|
170
|
+
bind(el, bindings, vnode);
|
|
172
171
|
}
|
|
173
172
|
};
|
|
174
173
|
|
|
@@ -1,22 +1,5 @@
|
|
|
1
1
|
import { makePropCacheMixin } from '../utils/cache';
|
|
2
|
-
import { extend, isVue3 } from '../vue';
|
|
3
2
|
|
|
4
|
-
const
|
|
5
|
-
const attrsMixinVue3 = extend({
|
|
6
|
-
computed: {
|
|
7
|
-
bvAttrs() {
|
|
8
|
-
const bvAttrs = {
|
|
9
|
-
...this.$attrs
|
|
10
|
-
};
|
|
11
|
-
Object.keys(bvAttrs).forEach(key => {
|
|
12
|
-
if (bvAttrs[key] === undefined) {
|
|
13
|
-
delete bvAttrs[key];
|
|
14
|
-
}
|
|
15
|
-
});
|
|
16
|
-
return bvAttrs;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
});
|
|
20
|
-
const attrsMixin = isVue3 ? attrsMixinVue3 : attrsMixinVue2;
|
|
3
|
+
const attrsMixin = makePropCacheMixin('$attrs', 'bvAttrs');
|
|
21
4
|
|
|
22
5
|
export { attrsMixin };
|
|
@@ -118,7 +118,7 @@ const dropdownMixin = extend({
|
|
|
118
118
|
this.visibleChangePrevented = true;
|
|
119
119
|
this.visible = oldValue;
|
|
120
120
|
// Just in case a child element triggered `this.hide(true)`
|
|
121
|
-
this.$
|
|
121
|
+
this.$_focusOnHidden = false;
|
|
122
122
|
return;
|
|
123
123
|
}
|
|
124
124
|
if (newValue) {
|
|
@@ -200,6 +200,11 @@ const dropdownMixin = extend({
|
|
|
200
200
|
this.emitOnRoot(ROOT_EVENT_NAME_HIDDEN, this);
|
|
201
201
|
this.$emit(EVENT_NAME_HIDDEN);
|
|
202
202
|
this.destroyPopper();
|
|
203
|
+
// Handle pending focus request
|
|
204
|
+
if (this.$_focusOnHidden) {
|
|
205
|
+
this.$_focusOnHidden = false;
|
|
206
|
+
this.focusToggler();
|
|
207
|
+
}
|
|
203
208
|
},
|
|
204
209
|
createPopper(element) {
|
|
205
210
|
this.destroyPopper();
|
|
@@ -283,7 +288,7 @@ const dropdownMixin = extend({
|
|
|
283
288
|
this.visible = false;
|
|
284
289
|
if (refocus) {
|
|
285
290
|
// Child element is closing the dropdown on click
|
|
286
|
-
this.$
|
|
291
|
+
this.$_focusOnHidden = true;
|
|
287
292
|
}
|
|
288
293
|
},
|
|
289
294
|
// Called only by a button that toggles the menu
|
|
@@ -349,7 +354,7 @@ const dropdownMixin = extend({
|
|
|
349
354
|
this.visible = false;
|
|
350
355
|
stopEvent(event);
|
|
351
356
|
// Return focus to original trigger button
|
|
352
|
-
this.$
|
|
357
|
+
this.$_focusOnHidden = true;
|
|
353
358
|
}
|
|
354
359
|
},
|
|
355
360
|
// Called only in split button mode, for the split button
|
|
@@ -1,24 +1,25 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { isVue3 } from '../vue';
|
|
2
|
+
import { getInternalPropName, makePropCacheMixin } from '../utils/cache';
|
|
3
3
|
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
data() {
|
|
7
|
-
return {
|
|
8
|
-
bvListeners: {}
|
|
9
|
-
};
|
|
10
|
-
},
|
|
4
|
+
const internalPropName = getInternalPropName('bvListeners');
|
|
5
|
+
const listenersMixin = makePropCacheMixin('$listeners', 'bvListeners').extend({
|
|
11
6
|
created() {
|
|
12
|
-
this
|
|
7
|
+
if (!isVue3(this)) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
this[internalPropName] = {
|
|
11
|
+
// bug: this.$listeners is non-reactive in Vue.js 3 compat
|
|
13
12
|
...this.$listeners
|
|
14
13
|
};
|
|
15
14
|
},
|
|
16
15
|
beforeUpdate() {
|
|
17
|
-
this
|
|
16
|
+
if (!isVue3(this)) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
this[internalPropName] = {
|
|
18
20
|
...this.$listeners
|
|
19
21
|
};
|
|
20
22
|
}
|
|
21
23
|
});
|
|
22
|
-
const listenersMixin = isVue3 ? listenersMixinVue3 : listenersMixinVue2;
|
|
23
24
|
|
|
24
25
|
export { listenersMixin };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { extend } from '../vue';
|
|
1
|
+
import { extend, isVue3 } from '../vue';
|
|
2
2
|
import { cloneDeep } from './clone-deep';
|
|
3
3
|
import { looseEqual } from './loose-equal';
|
|
4
4
|
import { hasOwnProperty, keys } from './object';
|
|
@@ -23,16 +23,38 @@ const makePropWatcher = propName => ({
|
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
});
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
26
|
+
const getInternalPropName = proxyPropName => `bv_internal__${proxyPropName}`;
|
|
27
|
+
const makePropCacheMixin = (propName, proxyPropName) => {
|
|
28
|
+
const internalPropName = getInternalPropName(proxyPropName);
|
|
29
|
+
return extend({
|
|
30
|
+
data() {
|
|
31
|
+
return {
|
|
32
|
+
[internalPropName]: isVue3(this) ? null : cloneDeep(this[propName] || {})
|
|
33
|
+
};
|
|
34
|
+
},
|
|
35
|
+
computed: {
|
|
36
|
+
[proxyPropName]() {
|
|
37
|
+
if (internalPropName in this && this[internalPropName]) {
|
|
38
|
+
return this[internalPropName];
|
|
39
|
+
}
|
|
40
|
+
const result = {
|
|
41
|
+
...this[propName]
|
|
42
|
+
};
|
|
43
|
+
Object.keys(result).forEach(key => {
|
|
44
|
+
if (result[key] === undefined) {
|
|
45
|
+
delete result[key];
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
created() {
|
|
52
|
+
if (!isVue3(this)) {
|
|
53
|
+
// Work around unwanted re-renders: https://github.com/vuejs/vue/issues/10115
|
|
54
|
+
this.$watch(propName, makePropWatcher(internalPropName).handler);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
};
|
|
37
59
|
|
|
38
|
-
export { makePropCacheMixin, makePropWatcher };
|
|
60
|
+
export { getInternalPropName, makePropCacheMixin, makePropWatcher };
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { PROP_NAME, NAME } from '../constants/config';
|
|
1
|
+
import { NAME } from '../constants/config';
|
|
3
2
|
import { cloneDeep } from './clone-deep';
|
|
4
3
|
import { getRaw } from './get';
|
|
5
4
|
import { isPlainObject, isArray, isString, isUndefined } from './inspect';
|
|
@@ -59,23 +58,29 @@ class BvConfig {
|
|
|
59
58
|
}
|
|
60
59
|
}
|
|
61
60
|
|
|
61
|
+
// Module-level singleton instance
|
|
62
|
+
let bvConfig = null;
|
|
63
|
+
|
|
64
|
+
// Get or create the config instance
|
|
65
|
+
const getConfigInstance = () => {
|
|
66
|
+
if (!bvConfig) {
|
|
67
|
+
bvConfig = new BvConfig();
|
|
68
|
+
}
|
|
69
|
+
return bvConfig;
|
|
70
|
+
};
|
|
71
|
+
|
|
62
72
|
// Method for applying a global config
|
|
63
73
|
const setConfig = function () {
|
|
64
74
|
let config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
65
|
-
|
|
66
|
-
// Ensure we have a `$bvConfig` Object on the Vue prototype
|
|
67
|
-
// We set on Vue and OurVue just in case consumer has not set an alias of `vue`
|
|
68
|
-
Vue$1.prototype[PROP_NAME] = Vue.prototype[PROP_NAME] = Vue$1.prototype[PROP_NAME] || Vue.prototype[PROP_NAME] || new BvConfig();
|
|
69
|
-
// Apply the config values
|
|
70
|
-
Vue$1.prototype[PROP_NAME].setConfig(config);
|
|
75
|
+
getConfigInstance().setConfig(config);
|
|
71
76
|
};
|
|
72
77
|
|
|
73
78
|
// Method for resetting the user config
|
|
74
79
|
// Exported for testing purposes only
|
|
75
80
|
const resetConfig = () => {
|
|
76
|
-
if (
|
|
77
|
-
|
|
81
|
+
if (bvConfig) {
|
|
82
|
+
bvConfig.resetConfig();
|
|
78
83
|
}
|
|
79
84
|
};
|
|
80
85
|
|
|
81
|
-
export { resetConfig, setConfig };
|
|
86
|
+
export { getConfigInstance, resetConfig, setConfig };
|
|
@@ -1,27 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { PROP_NAME, DEFAULT_BREAKPOINT } from '../constants/config';
|
|
1
|
+
import { DEFAULT_BREAKPOINT } from '../constants/config';
|
|
3
2
|
import { cloneDeep } from './clone-deep';
|
|
3
|
+
import { getConfigInstance } from './config-set';
|
|
4
4
|
import { memoize } from './memoize';
|
|
5
5
|
|
|
6
|
-
// --- Constants ---
|
|
7
|
-
|
|
8
|
-
const VueProto = Vue.prototype;
|
|
9
|
-
|
|
10
6
|
// --- Getter methods ---
|
|
11
7
|
// All methods return a deep clone (immutable) copy of the config value,
|
|
12
8
|
// to prevent mutation of the user config object
|
|
13
9
|
|
|
14
10
|
// Get the current config
|
|
15
11
|
const getConfig = () => {
|
|
16
|
-
|
|
17
|
-
return bvConfig ? bvConfig.getConfig() : {};
|
|
12
|
+
return getConfigInstance().getConfig();
|
|
18
13
|
};
|
|
19
14
|
|
|
20
15
|
// Method to grab a config value based on a dotted/array notation key
|
|
21
16
|
const getConfigValue = function (key) {
|
|
22
17
|
let defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;
|
|
23
|
-
|
|
24
|
-
return bvConfig ? bvConfig.getConfigValue(key, defaultValue) : cloneDeep(defaultValue);
|
|
18
|
+
return getConfigInstance().getConfigValue(key, defaultValue);
|
|
25
19
|
};
|
|
26
20
|
|
|
27
21
|
// Method to grab a config value for a particular component
|
|
@@ -1,12 +1,111 @@
|
|
|
1
|
+
import { isVue3 } from '../vue';
|
|
2
|
+
|
|
3
|
+
// Regex to detect event handler props: onSomething or onSomethingOnce
|
|
4
|
+
const EVENT_HANDLER_RE = /^on([A-Z][a-zA-Z]*)$/;
|
|
5
|
+
const ONCE_SUFFIX = 'Once';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Converts an event name to a handler prop name.
|
|
9
|
+
* Use as computed property key with event constants: [eventProp(EVENT_NAME_HIDDEN)]
|
|
10
|
+
* @param {string} eventName - The event name (e.g., 'hidden', 'show', 'mouseenter')
|
|
11
|
+
* @param {Object} options - Options object
|
|
12
|
+
* @param {boolean} options.once - If true, returns the "once" variant (e.g., 'onHiddenOnce')
|
|
13
|
+
* @returns {string} The handler prop name (e.g., 'onHidden', 'onHiddenOnce')
|
|
14
|
+
*/
|
|
15
|
+
const eventProp = function (eventName) {
|
|
16
|
+
let {
|
|
17
|
+
once = false
|
|
18
|
+
} = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
19
|
+
const capitalized = eventName.charAt(0).toUpperCase() + eventName.slice(1);
|
|
20
|
+
return `on${capitalized}${once ? ONCE_SUFFIX : ''}`;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Parses a handler prop name to extract event name and once flag.
|
|
25
|
+
* Examples:
|
|
26
|
+
* onShow -> { eventName: 'show', once: false }
|
|
27
|
+
* onShowOnce -> { eventName: 'show', once: true }
|
|
28
|
+
* onMouseenter -> { eventName: 'mouseenter', once: false }
|
|
29
|
+
*/
|
|
30
|
+
const parseEventHandlerProp = propName => {
|
|
31
|
+
const match = propName.match(EVENT_HANDLER_RE);
|
|
32
|
+
if (!match) return null;
|
|
33
|
+
let eventPart = match[1];
|
|
34
|
+
const once = eventPart.endsWith(ONCE_SUFFIX);
|
|
35
|
+
if (once) eventPart = eventPart.slice(0, -ONCE_SUFFIX.length);
|
|
36
|
+
const eventName = eventPart.charAt(0).toLowerCase() + eventPart.slice(1);
|
|
37
|
+
return {
|
|
38
|
+
eventName,
|
|
39
|
+
once
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Extracts event handlers from config and separates them from other props.
|
|
45
|
+
* @param {Object} config - The config object with potential event handler props
|
|
46
|
+
* @returns {{ handlers: Array<{eventName: string, handler: Function, once: boolean}>, cleanConfig: Object }}
|
|
47
|
+
*/
|
|
48
|
+
const extractEventHandlers = config => {
|
|
49
|
+
const handlers = [];
|
|
50
|
+
const cleanConfig = {
|
|
51
|
+
...config
|
|
52
|
+
};
|
|
53
|
+
if (cleanConfig.propsData) {
|
|
54
|
+
const cleanPropsData = {};
|
|
55
|
+
Object.keys(cleanConfig.propsData).forEach(propName => {
|
|
56
|
+
const parsed = parseEventHandlerProp(propName);
|
|
57
|
+
if (parsed && typeof cleanConfig.propsData[propName] === 'function') {
|
|
58
|
+
handlers.push({
|
|
59
|
+
...parsed,
|
|
60
|
+
handler: cleanConfig.propsData[propName]
|
|
61
|
+
});
|
|
62
|
+
} else {
|
|
63
|
+
cleanPropsData[propName] = cleanConfig.propsData[propName];
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
cleanConfig.propsData = cleanPropsData;
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
handlers,
|
|
70
|
+
cleanConfig
|
|
71
|
+
};
|
|
72
|
+
};
|
|
1
73
|
const createNewChildComponent = function (parent, Component) {
|
|
2
74
|
let config = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
3
75
|
const bvEventRoot = parent.$root ? parent.$root.$options.bvEventRoot || parent.$root : null;
|
|
4
|
-
|
|
5
|
-
|
|
76
|
+
|
|
77
|
+
// Vue 3: pass handlers as props directly (Vue 3 converts onXxx props to listeners)
|
|
78
|
+
if (isVue3(parent)) {
|
|
79
|
+
return new Component({
|
|
80
|
+
...config,
|
|
81
|
+
parent,
|
|
82
|
+
bvParent: parent,
|
|
83
|
+
bvEventRoot
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Vue 2: extract handlers and subscribe manually after creation
|
|
88
|
+
const {
|
|
89
|
+
handlers,
|
|
90
|
+
cleanConfig
|
|
91
|
+
} = extractEventHandlers(config);
|
|
92
|
+
const instance = new Component({
|
|
93
|
+
...cleanConfig,
|
|
6
94
|
parent,
|
|
7
95
|
bvParent: parent,
|
|
8
96
|
bvEventRoot
|
|
9
97
|
});
|
|
98
|
+
|
|
99
|
+
// Subscribe to events using $on/$once
|
|
100
|
+
handlers.forEach(_ref => {
|
|
101
|
+
let {
|
|
102
|
+
eventName,
|
|
103
|
+
handler,
|
|
104
|
+
once
|
|
105
|
+
} = _ref;
|
|
106
|
+
instance[once ? '$once' : '$on'](eventName, handler);
|
|
107
|
+
});
|
|
108
|
+
return instance;
|
|
10
109
|
};
|
|
11
110
|
|
|
12
|
-
export { createNewChildComponent };
|
|
111
|
+
export { createNewChildComponent, eventProp };
|
|
@@ -1,23 +1,17 @@
|
|
|
1
1
|
import { isVue3 } from '../vue';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
if (isVue3) {
|
|
5
|
-
registry = new WeakMap();
|
|
6
|
-
}
|
|
3
|
+
const registry = new WeakMap();
|
|
7
4
|
const registerElementToInstance = (element, instance) => {
|
|
8
|
-
if (!isVue3) {
|
|
5
|
+
if (!isVue3(instance)) {
|
|
9
6
|
return;
|
|
10
7
|
}
|
|
11
8
|
registry.set(element, instance);
|
|
12
9
|
};
|
|
13
10
|
const removeElementToInstance = element => {
|
|
14
|
-
if (!isVue3) {
|
|
15
|
-
return;
|
|
16
|
-
}
|
|
17
11
|
registry.delete(element);
|
|
18
12
|
};
|
|
19
13
|
const getInstanceFromElement = element => {
|
|
20
|
-
if (
|
|
14
|
+
if (element.__vue__) {
|
|
21
15
|
return element.__vue__;
|
|
22
16
|
}
|
|
23
17
|
let currentElement = element;
|