@gitlab/ui 131.3.2 → 132.0.1
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/package.json +4 -3
- package/src/components/base/form/form_checkbox/form_checkbox_group.vue +4 -2
- package/src/components/base/form/form_radio_group/form_radio_group.vue +4 -2
- package/src/components/base/link/link.vue +5 -8
- package/src/utils/constants.js +0 -3
- package/src/utils/form_options_utils.js +39 -0
- package/src/utils/vue_utils.js +56 -0
- package/src/vendor/bootstrap-vue/src/components/modal/modal.js +217 -50
- package/src/vendor/bootstrap-vue/src/components/table/helpers/mixin-filtering.js +30 -11
- package/src/vendor/bootstrap-vue/src/components/table/helpers/mixin-selectable.js +3 -3
- package/src/vendor/bootstrap-vue/src/components/table/helpers/mixin-sorting.js +1 -2
- package/src/vendor/bootstrap-vue/src/components/table/helpers/mixin-tbody.js +4 -4
- package/src/vendor/bootstrap-vue/src/components/table/helpers/sanitize-row.js +2 -3
- package/src/vendor/bootstrap-vue/src/components/tabs/tabs.js +116 -25
- package/src/vendor/bootstrap-vue/src/constants/config.js +2 -2
- package/src/vendor/bootstrap-vue/src/directives/tooltip/tooltip.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gitlab/ui",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "132.0.1",
|
|
4
4
|
"description": "GitLab UI Components",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -103,6 +103,7 @@
|
|
|
103
103
|
"@cypress/grep": "^4.1.1",
|
|
104
104
|
"@figma/code-connect": "^1.4.3",
|
|
105
105
|
"@gitlab/fonts": "^1.3.1",
|
|
106
|
+
"@gitlab/hybrid-vue": "npm:@vue/compat@3.5.30",
|
|
106
107
|
"@gitlab/svgs": "*",
|
|
107
108
|
"@jest/test-sequencer": "30.3.0",
|
|
108
109
|
"@rollup/plugin-commonjs": "^28.0.9",
|
|
@@ -132,10 +133,10 @@
|
|
|
132
133
|
"@yarnpkg/lockfile": "^1.1.0",
|
|
133
134
|
"acorn": "^8.16.0",
|
|
134
135
|
"acorn-walk": "^8.3.5",
|
|
135
|
-
"autoprefixer": "10.
|
|
136
|
+
"autoprefixer": "10.5.0",
|
|
136
137
|
"axe-playwright": "^2.2.2",
|
|
137
138
|
"babel-loader": "^9.2.1",
|
|
138
|
-
"cypress": "15.
|
|
139
|
+
"cypress": "15.14.0",
|
|
139
140
|
"cypress-real-events": "^1.15.0",
|
|
140
141
|
"dompurify": "^3.1.2",
|
|
141
142
|
"emoji-regex": "^10.6.0",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { uniqueId, isBoolean, omit, pick } from 'lodash-es';
|
|
3
3
|
import { looseEqual } from '../../../../utils/equality_utils';
|
|
4
|
-
import { formOptionsMixin } from '../../../../vendor/bootstrap-vue/src/mixins/form-options';
|
|
5
4
|
import { SafeHtmlDirective as SafeHtml } from '../../../../directives/safe_html/safe_html';
|
|
5
|
+
import { normalizeOptions } from '../../../../utils/form_options_utils';
|
|
6
6
|
import GlFormCheckbox from './form_checkbox.vue';
|
|
7
7
|
|
|
8
8
|
// Attributes to pass down to checks/radios instead of applying them to the group
|
|
@@ -14,7 +14,6 @@ export default {
|
|
|
14
14
|
directives: {
|
|
15
15
|
SafeHtml,
|
|
16
16
|
},
|
|
17
|
-
mixins: [formOptionsMixin],
|
|
18
17
|
provide() {
|
|
19
18
|
return {
|
|
20
19
|
getCheckboxGroup: () => this,
|
|
@@ -98,6 +97,9 @@ export default {
|
|
|
98
97
|
};
|
|
99
98
|
},
|
|
100
99
|
computed: {
|
|
100
|
+
formOptions() {
|
|
101
|
+
return normalizeOptions(this.options);
|
|
102
|
+
},
|
|
101
103
|
computedState() {
|
|
102
104
|
return isBoolean(this.state) ? this.state : null;
|
|
103
105
|
},
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { uniqueId, isBoolean, omit, pick } from 'lodash-es';
|
|
3
3
|
import { looseEqual } from '../../../../utils/equality_utils';
|
|
4
|
-
import { formOptionsMixin } from '../../../../vendor/bootstrap-vue/src/mixins/form-options';
|
|
5
4
|
import { SafeHtmlDirective as SafeHtml } from '../../../../directives/safe_html/safe_html';
|
|
5
|
+
import { normalizeOptions } from '../../../../utils/form_options_utils';
|
|
6
6
|
import GlFormRadio from '../form_radio/form_radio.vue';
|
|
7
7
|
|
|
8
8
|
// Attributes to pass down to checks/radios instead of applying them to the group
|
|
@@ -16,7 +16,6 @@ export default {
|
|
|
16
16
|
directives: {
|
|
17
17
|
SafeHtml,
|
|
18
18
|
},
|
|
19
|
-
mixins: [formOptionsMixin],
|
|
20
19
|
provide() {
|
|
21
20
|
return {
|
|
22
21
|
getRadioGroup: () => this,
|
|
@@ -101,6 +100,9 @@ export default {
|
|
|
101
100
|
};
|
|
102
101
|
},
|
|
103
102
|
computed: {
|
|
103
|
+
formOptions() {
|
|
104
|
+
return normalizeOptions(this.options);
|
|
105
|
+
},
|
|
104
106
|
computedState() {
|
|
105
107
|
return isBoolean(this.state) ? this.state : null;
|
|
106
108
|
},
|
|
@@ -2,16 +2,13 @@
|
|
|
2
2
|
import { isFunction, isString, isObject, toString, isBoolean, concat } from 'lodash-es';
|
|
3
3
|
import { SafeLinkDirective, isExternalURL } from '../../../directives/safe_link/safe_link';
|
|
4
4
|
import { stopEvent } from '../../../utils/utils';
|
|
5
|
-
import {
|
|
5
|
+
import { isVue3, safeVueInstance } from '../../../utils/vue_utils';
|
|
6
6
|
import { stringifyQueryObj } from '../../../vendor/bootstrap-vue/src/utils/router';
|
|
7
|
-
import { safeVueInstance } from '../../../vendor/bootstrap-vue/src/utils/safe-vue-instance';
|
|
8
|
-
import { attemptFocus, attemptBlur } from '../../../vendor/bootstrap-vue/src/utils/dom';
|
|
9
7
|
import {
|
|
10
8
|
linkVariantOptions,
|
|
11
9
|
linkVariantInline,
|
|
12
10
|
linkVariantMeta,
|
|
13
11
|
linkVariantUnstyled,
|
|
14
|
-
isVue3,
|
|
15
12
|
} from '../../../utils/constants';
|
|
16
13
|
|
|
17
14
|
const ANCHOR_TAG = 'a';
|
|
@@ -162,7 +159,7 @@ export default {
|
|
|
162
159
|
return this.tag !== ANCHOR_TAG;
|
|
163
160
|
},
|
|
164
161
|
isVue3RouterLink() {
|
|
165
|
-
return this.tag === VUE_ROUTER_LINK_TAG && isVue3;
|
|
162
|
+
return this.tag === VUE_ROUTER_LINK_TAG && isVue3(this);
|
|
166
163
|
},
|
|
167
164
|
shouldShowExternalIcon() {
|
|
168
165
|
const allowedVariants = [linkVariantInline, linkVariantMeta, null]; // null represents default/UI variant
|
|
@@ -250,7 +247,7 @@ export default {
|
|
|
250
247
|
},
|
|
251
248
|
methods: {
|
|
252
249
|
onClick(event, navigate) {
|
|
253
|
-
const eventIsEvent =
|
|
250
|
+
const eventIsEvent = event instanceof Event;
|
|
254
251
|
const suppliedHandler = this.$listeners.click;
|
|
255
252
|
|
|
256
253
|
if (eventIsEvent && this.disabled) {
|
|
@@ -292,10 +289,10 @@ export default {
|
|
|
292
289
|
}
|
|
293
290
|
},
|
|
294
291
|
focus() {
|
|
295
|
-
|
|
292
|
+
this.$el.focus();
|
|
296
293
|
},
|
|
297
294
|
blur() {
|
|
298
|
-
|
|
295
|
+
this.$el.blur();
|
|
299
296
|
},
|
|
300
297
|
},
|
|
301
298
|
};
|
package/src/utils/constants.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import Vue from 'vue';
|
|
2
1
|
import { POSITION } from '../components/utilities/truncate/constants';
|
|
3
2
|
|
|
4
3
|
export const COMMA = ',';
|
|
@@ -385,5 +384,3 @@ export const loadingIconVariants = {
|
|
|
385
384
|
spinner: 'spinner',
|
|
386
385
|
dots: 'dots',
|
|
387
386
|
};
|
|
388
|
-
|
|
389
|
-
export const isVue3 = Boolean(Vue.Fragment);
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalizes a single option into a standard { value, text, html, disabled } shape.
|
|
3
|
+
*/
|
|
4
|
+
function normalizeOption(option) {
|
|
5
|
+
if (option !== null && typeof option === 'object') {
|
|
6
|
+
const { value, text, html, disabled } = option;
|
|
7
|
+
return {
|
|
8
|
+
value: value === undefined ? text : value,
|
|
9
|
+
text: String(text),
|
|
10
|
+
html,
|
|
11
|
+
disabled: Boolean(disabled),
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
return {
|
|
15
|
+
value: option,
|
|
16
|
+
text: String(option),
|
|
17
|
+
disabled: false,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Normalizes an options array into a consistent format for rendering.
|
|
23
|
+
*
|
|
24
|
+
* Each option can be a primitive (string, number) or an object with
|
|
25
|
+
* `{ value, text, html, disabled }` properties. Primitives are converted
|
|
26
|
+
* to `{ value, text, disabled: false }`. For objects, `value` defaults to
|
|
27
|
+
* `text` when omitted and `disabled` defaults to `false`.
|
|
28
|
+
*
|
|
29
|
+
* @param {Array<string|number|{value?: *, text: string, html?: string, disabled?: boolean}>} options
|
|
30
|
+
* The raw options array to normalize.
|
|
31
|
+
* @returns {Array<{value: *, text: string, html?: string, disabled: boolean}>}
|
|
32
|
+
* The normalized options, or an empty array if the input is not an array.
|
|
33
|
+
*/
|
|
34
|
+
export function normalizeOptions(options) {
|
|
35
|
+
if (Array.isArray(options)) {
|
|
36
|
+
return options.map((option) => normalizeOption(option));
|
|
37
|
+
}
|
|
38
|
+
return [];
|
|
39
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import Vue from 'vue';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Checks whether the global Vue version is Vue 3 (or the Vue 3 compat build).
|
|
5
|
+
*
|
|
6
|
+
* Use this for module-level checks where no component instance is available,
|
|
7
|
+
* such as conditional test logic or static configuration.
|
|
8
|
+
*
|
|
9
|
+
* @type {boolean}
|
|
10
|
+
*/
|
|
11
|
+
export const isGlobalVue3 = Boolean(Vue.Fragment);
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Checks whether a component instance is running under Vue 3 (or compat mode).
|
|
15
|
+
*
|
|
16
|
+
* In Vue 3, component instances expose an internal `$` property that holds
|
|
17
|
+
* the component's internal instance. This property does not exist in Vue 2.
|
|
18
|
+
*
|
|
19
|
+
* Prefer this over {@link isGlobalVue3} when you have access to a component
|
|
20
|
+
* instance, as it checks at the instance level rather than the global level.
|
|
21
|
+
*
|
|
22
|
+
* @param {object} instance - The Vue component instance (`this`).
|
|
23
|
+
* @returns {boolean} `true` if the instance is a Vue 3 component.
|
|
24
|
+
*/
|
|
25
|
+
export const isVue3 = (instance) => Boolean(instance.$);
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Wraps a Vue component instance to safely access properties without
|
|
29
|
+
* triggering Vue 3 development warnings.
|
|
30
|
+
*
|
|
31
|
+
* In Vue 3 (and compat mode), component instances are Proxies. Accessing a
|
|
32
|
+
* property that doesn't exist on the instance (e.g. `this.$router` when no
|
|
33
|
+
* router is installed) triggers a development warning from Vue's `get` trap:
|
|
34
|
+
* "Property X was accessed during render but is not defined on instance."
|
|
35
|
+
*
|
|
36
|
+
* This utility returns a Proxy that uses the `in` operator (which hits Vue's
|
|
37
|
+
* `has` trap, which is silent) to check for property existence before accessing
|
|
38
|
+
* it. If the property doesn't exist, `undefined` is returned without ever
|
|
39
|
+
* hitting Vue's `get` trap.
|
|
40
|
+
*
|
|
41
|
+
* In Vue 2, the instance is returned as-is since there are no Proxy warnings.
|
|
42
|
+
*
|
|
43
|
+
* @param {object} target - The Vue component instance (`this`).
|
|
44
|
+
* @returns {object} The original instance (Vue 2) or a safe Proxy wrapper (Vue 3).
|
|
45
|
+
*/
|
|
46
|
+
export function safeVueInstance(target) {
|
|
47
|
+
if (!isVue3(target)) {
|
|
48
|
+
return target;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return new Proxy(target, {
|
|
52
|
+
get(obj, prop) {
|
|
53
|
+
return prop in obj ? obj[prop] : undefined;
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
}
|
|
@@ -15,8 +15,7 @@ import {
|
|
|
15
15
|
} from '../../constants/events'
|
|
16
16
|
import { CODE_ESC } from '../../constants/key-codes'
|
|
17
17
|
import {
|
|
18
|
-
|
|
19
|
-
PROP_TYPE_ARRAY_STRING,
|
|
18
|
+
PROP_TYPE_ARRAY,
|
|
20
19
|
PROP_TYPE_BOOLEAN,
|
|
21
20
|
PROP_TYPE_OBJECT,
|
|
22
21
|
PROP_TYPE_STRING
|
|
@@ -49,7 +48,6 @@ import { isString, isUndefinedOrNull } from '../../utils/inspect'
|
|
|
49
48
|
import { makeModelMixin } from '../../utils/model'
|
|
50
49
|
import { sortKeys } from '../../utils/object'
|
|
51
50
|
import { observeDom } from '../../utils/observe-dom'
|
|
52
|
-
import { makeProp } from '../../utils/props'
|
|
53
51
|
import { attrsMixin } from '../../mixins/attrs'
|
|
54
52
|
import { idMixin, props as idProps } from '../../mixins/id'
|
|
55
53
|
import { listenOnDocumentMixin } from '../../mixins/listen-on-document'
|
|
@@ -104,60 +102,229 @@ const OBSERVER_CONFIG = {
|
|
|
104
102
|
export const props = sortKeys({
|
|
105
103
|
...idProps,
|
|
106
104
|
...modelProps,
|
|
107
|
-
ariaLabel:
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
105
|
+
ariaLabel: {
|
|
106
|
+
type: PROP_TYPE_STRING,
|
|
107
|
+
required: false,
|
|
108
|
+
default: undefined
|
|
109
|
+
},
|
|
110
|
+
autoFocusButton: {
|
|
111
|
+
type: PROP_TYPE_STRING,
|
|
112
|
+
required: false,
|
|
113
|
+
default: null,
|
|
114
|
+
validator: value => {
|
|
112
115
|
return isUndefinedOrNull(value) || arrayIncludes(BUTTONS, value)
|
|
113
116
|
}
|
|
114
|
-
|
|
115
|
-
bodyClass:
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
117
|
+
},
|
|
118
|
+
bodyClass: {
|
|
119
|
+
type: [PROP_TYPE_ARRAY, PROP_TYPE_OBJECT, PROP_TYPE_STRING],
|
|
120
|
+
required: false,
|
|
121
|
+
default: undefined
|
|
122
|
+
},
|
|
123
|
+
busy: {
|
|
124
|
+
type: PROP_TYPE_BOOLEAN,
|
|
125
|
+
required: false,
|
|
126
|
+
default: false
|
|
127
|
+
},
|
|
128
|
+
buttonSize: {
|
|
129
|
+
type: PROP_TYPE_STRING,
|
|
130
|
+
required: false,
|
|
131
|
+
default: undefined
|
|
132
|
+
},
|
|
133
|
+
cancelDisabled: {
|
|
134
|
+
type: PROP_TYPE_BOOLEAN,
|
|
135
|
+
required: false,
|
|
136
|
+
default: false
|
|
137
|
+
},
|
|
138
|
+
cancelTitle: {
|
|
139
|
+
type: PROP_TYPE_STRING,
|
|
140
|
+
required: false,
|
|
141
|
+
default: 'Cancel'
|
|
142
|
+
},
|
|
143
|
+
cancelTitleHtml: {
|
|
144
|
+
type: PROP_TYPE_STRING,
|
|
145
|
+
required: false,
|
|
146
|
+
default: undefined
|
|
147
|
+
},
|
|
148
|
+
cancelVariant: {
|
|
149
|
+
type: PROP_TYPE_STRING,
|
|
150
|
+
required: false,
|
|
151
|
+
default: 'secondary'
|
|
152
|
+
},
|
|
153
|
+
centered: {
|
|
154
|
+
type: PROP_TYPE_BOOLEAN,
|
|
155
|
+
required: false,
|
|
156
|
+
default: false
|
|
157
|
+
},
|
|
158
|
+
contentClass: {
|
|
159
|
+
type: [PROP_TYPE_ARRAY, PROP_TYPE_OBJECT, PROP_TYPE_STRING],
|
|
160
|
+
required: false,
|
|
161
|
+
default: undefined
|
|
162
|
+
},
|
|
163
|
+
dialogClass: {
|
|
164
|
+
type: [PROP_TYPE_ARRAY, PROP_TYPE_OBJECT, PROP_TYPE_STRING],
|
|
165
|
+
required: false,
|
|
166
|
+
default: undefined
|
|
167
|
+
},
|
|
168
|
+
footerClass: {
|
|
169
|
+
type: [PROP_TYPE_ARRAY, PROP_TYPE_OBJECT, PROP_TYPE_STRING],
|
|
170
|
+
required: false,
|
|
171
|
+
default: undefined
|
|
172
|
+
},
|
|
173
|
+
footerTag: {
|
|
174
|
+
type: PROP_TYPE_STRING,
|
|
175
|
+
required: false,
|
|
176
|
+
default: 'footer'
|
|
177
|
+
},
|
|
178
|
+
headerClass: {
|
|
179
|
+
type: [PROP_TYPE_ARRAY, PROP_TYPE_OBJECT, PROP_TYPE_STRING],
|
|
180
|
+
required: false,
|
|
181
|
+
default: undefined
|
|
182
|
+
},
|
|
183
|
+
headerCloseContent: {
|
|
184
|
+
type: PROP_TYPE_STRING,
|
|
185
|
+
required: false,
|
|
186
|
+
default: '×'
|
|
187
|
+
},
|
|
188
|
+
headerCloseLabel: {
|
|
189
|
+
type: PROP_TYPE_STRING,
|
|
190
|
+
required: false,
|
|
191
|
+
default: 'Close'
|
|
192
|
+
},
|
|
193
|
+
headerTag: {
|
|
194
|
+
type: PROP_TYPE_STRING,
|
|
195
|
+
required: false,
|
|
196
|
+
default: 'header'
|
|
197
|
+
},
|
|
131
198
|
// TODO: Rename to `noBackdrop` and deprecate `hideBackdrop`
|
|
132
|
-
hideBackdrop:
|
|
199
|
+
hideBackdrop: {
|
|
200
|
+
type: PROP_TYPE_BOOLEAN,
|
|
201
|
+
required: false,
|
|
202
|
+
default: false
|
|
203
|
+
},
|
|
133
204
|
// TODO: Rename to `noFooter` and deprecate `hideFooter`
|
|
134
|
-
hideFooter:
|
|
205
|
+
hideFooter: {
|
|
206
|
+
type: PROP_TYPE_BOOLEAN,
|
|
207
|
+
required: false,
|
|
208
|
+
default: false
|
|
209
|
+
},
|
|
135
210
|
// TODO: Rename to `noHeader` and deprecate `hideHeader`
|
|
136
|
-
hideHeader:
|
|
211
|
+
hideHeader: {
|
|
212
|
+
type: PROP_TYPE_BOOLEAN,
|
|
213
|
+
required: false,
|
|
214
|
+
default: false
|
|
215
|
+
},
|
|
137
216
|
// TODO: Rename to `noHeaderClose` and deprecate `hideHeaderClose`
|
|
138
|
-
hideHeaderClose:
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
217
|
+
hideHeaderClose: {
|
|
218
|
+
type: PROP_TYPE_BOOLEAN,
|
|
219
|
+
required: false,
|
|
220
|
+
default: false
|
|
221
|
+
},
|
|
222
|
+
ignoreEnforceFocusSelector: {
|
|
223
|
+
type: [PROP_TYPE_ARRAY, PROP_TYPE_STRING],
|
|
224
|
+
required: false,
|
|
225
|
+
default: undefined
|
|
226
|
+
},
|
|
227
|
+
lazy: {
|
|
228
|
+
type: PROP_TYPE_BOOLEAN,
|
|
229
|
+
required: false,
|
|
230
|
+
default: false
|
|
231
|
+
},
|
|
232
|
+
modalClass: {
|
|
233
|
+
type: [PROP_TYPE_ARRAY, PROP_TYPE_OBJECT, PROP_TYPE_STRING],
|
|
234
|
+
required: false,
|
|
235
|
+
default: undefined
|
|
236
|
+
},
|
|
237
|
+
noCloseOnBackdrop: {
|
|
238
|
+
type: PROP_TYPE_BOOLEAN,
|
|
239
|
+
required: false,
|
|
240
|
+
default: false
|
|
241
|
+
},
|
|
242
|
+
noCloseOnEsc: {
|
|
243
|
+
type: PROP_TYPE_BOOLEAN,
|
|
244
|
+
required: false,
|
|
245
|
+
default: false
|
|
246
|
+
},
|
|
247
|
+
noEnforceFocus: {
|
|
248
|
+
type: PROP_TYPE_BOOLEAN,
|
|
249
|
+
required: false,
|
|
250
|
+
default: false
|
|
251
|
+
},
|
|
252
|
+
noFade: {
|
|
253
|
+
type: PROP_TYPE_BOOLEAN,
|
|
254
|
+
required: false,
|
|
255
|
+
default: false
|
|
256
|
+
},
|
|
257
|
+
noStacking: {
|
|
258
|
+
type: PROP_TYPE_BOOLEAN,
|
|
259
|
+
required: false,
|
|
260
|
+
default: false
|
|
261
|
+
},
|
|
262
|
+
okDisabled: {
|
|
263
|
+
type: PROP_TYPE_BOOLEAN,
|
|
264
|
+
required: false,
|
|
265
|
+
default: false
|
|
266
|
+
},
|
|
267
|
+
okOnly: {
|
|
268
|
+
type: PROP_TYPE_BOOLEAN,
|
|
269
|
+
required: false,
|
|
270
|
+
default: false
|
|
271
|
+
},
|
|
272
|
+
okTitle: {
|
|
273
|
+
type: PROP_TYPE_STRING,
|
|
274
|
+
required: false,
|
|
275
|
+
default: 'OK'
|
|
276
|
+
},
|
|
277
|
+
okTitleHtml: {
|
|
278
|
+
type: PROP_TYPE_STRING,
|
|
279
|
+
required: false,
|
|
280
|
+
default: undefined
|
|
281
|
+
},
|
|
282
|
+
okVariant: {
|
|
283
|
+
type: PROP_TYPE_STRING,
|
|
284
|
+
required: false,
|
|
285
|
+
default: 'primary'
|
|
286
|
+
},
|
|
152
287
|
// HTML Element, CSS selector string or Vue component instance
|
|
153
|
-
returnFocus:
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
288
|
+
returnFocus: {
|
|
289
|
+
type: [HTMLElement, PROP_TYPE_OBJECT, PROP_TYPE_STRING],
|
|
290
|
+
required: false,
|
|
291
|
+
default: undefined
|
|
292
|
+
},
|
|
293
|
+
scrollable: {
|
|
294
|
+
type: PROP_TYPE_BOOLEAN,
|
|
295
|
+
required: false,
|
|
296
|
+
default: false
|
|
297
|
+
},
|
|
298
|
+
size: {
|
|
299
|
+
type: PROP_TYPE_STRING,
|
|
300
|
+
required: false,
|
|
301
|
+
default: 'md'
|
|
302
|
+
},
|
|
303
|
+
static: {
|
|
304
|
+
type: PROP_TYPE_BOOLEAN,
|
|
305
|
+
required: false,
|
|
306
|
+
default: false
|
|
307
|
+
},
|
|
308
|
+
title: {
|
|
309
|
+
type: PROP_TYPE_STRING,
|
|
310
|
+
required: false,
|
|
311
|
+
default: undefined
|
|
312
|
+
},
|
|
313
|
+
titleClass: {
|
|
314
|
+
type: [PROP_TYPE_ARRAY, PROP_TYPE_OBJECT, PROP_TYPE_STRING],
|
|
315
|
+
required: false,
|
|
316
|
+
default: undefined
|
|
317
|
+
},
|
|
318
|
+
titleHtml: {
|
|
319
|
+
type: PROP_TYPE_STRING,
|
|
320
|
+
required: false,
|
|
321
|
+
default: undefined
|
|
322
|
+
},
|
|
323
|
+
titleTag: {
|
|
324
|
+
type: PROP_TYPE_STRING,
|
|
325
|
+
required: false,
|
|
326
|
+
default: 'h5'
|
|
327
|
+
}
|
|
161
328
|
})
|
|
162
329
|
|
|
163
330
|
// --- Main component ---
|
|
@@ -3,10 +3,11 @@ import { NAME_TABLE } from '../../../constants/components'
|
|
|
3
3
|
import { EVENT_NAME_FILTERED } from '../../../constants/events'
|
|
4
4
|
import {
|
|
5
5
|
PROP_TYPE_REG_EXP,
|
|
6
|
-
PROP_TYPE_ARRAY_OBJECT_STRING,
|
|
7
|
-
PROP_TYPE_FUNCTION,
|
|
8
6
|
PROP_TYPE_ARRAY,
|
|
9
|
-
|
|
7
|
+
PROP_TYPE_FUNCTION,
|
|
8
|
+
PROP_TYPE_NUMBER,
|
|
9
|
+
PROP_TYPE_OBJECT,
|
|
10
|
+
PROP_TYPE_STRING
|
|
10
11
|
} from '../../../constants/props'
|
|
11
12
|
import { RX_DIGITS, RX_SPACES } from '../../../constants/regex'
|
|
12
13
|
import { concat } from '../../../utils/array'
|
|
@@ -15,7 +16,6 @@ import { identity } from '../../../utils/identity'
|
|
|
15
16
|
import { isFunction, isString, isRegExp } from '../../../utils/inspect'
|
|
16
17
|
import { looseEqual } from '../../../utils/loose-equal'
|
|
17
18
|
import { toInteger } from '../../../utils/number'
|
|
18
|
-
import { makeProp } from '../../../utils/props'
|
|
19
19
|
import { escapeRegExp } from '../../../utils/string'
|
|
20
20
|
import { warn } from '../../../utils/warn'
|
|
21
21
|
import { stringifyRecordValues } from './stringify-record-values'
|
|
@@ -28,13 +28,32 @@ const DEBOUNCE_DEPRECATED_MSG =
|
|
|
28
28
|
// --- Props ---
|
|
29
29
|
|
|
30
30
|
export const props = {
|
|
31
|
-
filter:
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
31
|
+
filter: {
|
|
32
|
+
type: [PROP_TYPE_ARRAY, PROP_TYPE_OBJECT, PROP_TYPE_STRING, PROP_TYPE_REG_EXP],
|
|
33
|
+
required: false,
|
|
34
|
+
default: undefined
|
|
35
|
+
},
|
|
36
|
+
filterDebounce: {
|
|
37
|
+
type: [PROP_TYPE_NUMBER, PROP_TYPE_STRING],
|
|
38
|
+
required: false,
|
|
39
|
+
default: 0,
|
|
40
|
+
validator: value => RX_DIGITS.test(String(value))
|
|
41
|
+
},
|
|
42
|
+
filterFunction: {
|
|
43
|
+
type: PROP_TYPE_FUNCTION,
|
|
44
|
+
required: false,
|
|
45
|
+
default: undefined
|
|
46
|
+
},
|
|
47
|
+
filterIgnoredFields: {
|
|
48
|
+
type: PROP_TYPE_ARRAY,
|
|
49
|
+
required: false,
|
|
50
|
+
default: () => []
|
|
51
|
+
},
|
|
52
|
+
filterIncludedFields: {
|
|
53
|
+
type: PROP_TYPE_ARRAY,
|
|
54
|
+
required: false,
|
|
55
|
+
default: () => []
|
|
56
|
+
}
|
|
38
57
|
}
|
|
39
58
|
|
|
40
59
|
// --- Mixin ---
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { extend } from '../../../vue'
|
|
2
2
|
import { EVENT_NAME_ROW_SELECTED } from '../../../constants/events'
|
|
3
3
|
import { PROP_TYPE_BOOLEAN, PROP_TYPE_STRING } from '../../../constants/props'
|
|
4
|
-
import {
|
|
4
|
+
import { createArray } from '../../../utils/array'
|
|
5
5
|
import { identity } from '../../../utils/identity'
|
|
6
6
|
import { isArray, isNumber } from '../../../utils/inspect'
|
|
7
7
|
import { looseEqual } from '../../../utils/loose-equal'
|
|
@@ -22,7 +22,7 @@ export const props = {
|
|
|
22
22
|
// Disable use of click handlers for row selection
|
|
23
23
|
noSelectOnClick: makeProp(PROP_TYPE_BOOLEAN, false),
|
|
24
24
|
selectMode: makeProp(PROP_TYPE_STRING, 'multi', value => {
|
|
25
|
-
return
|
|
25
|
+
return SELECT_MODES.includes(value)
|
|
26
26
|
}),
|
|
27
27
|
selectable: makeProp(PROP_TYPE_BOOLEAN, false),
|
|
28
28
|
selectedVariant: makeProp(PROP_TYPE_STRING, 'active')
|
|
@@ -56,7 +56,7 @@ export const selectableMixin = extend({
|
|
|
56
56
|
)
|
|
57
57
|
},
|
|
58
58
|
selectableIsMultiSelect() {
|
|
59
|
-
return this.isSelectable &&
|
|
59
|
+
return this.isSelectable && ['range', 'multi'].includes(this.selectMode)
|
|
60
60
|
},
|
|
61
61
|
selectableTableClasses() {
|
|
62
62
|
const { isSelectable } = this
|
|
@@ -7,7 +7,6 @@ import {
|
|
|
7
7
|
PROP_TYPE_OBJECT,
|
|
8
8
|
PROP_TYPE_STRING
|
|
9
9
|
} from '../../../constants/props'
|
|
10
|
-
import { arrayIncludes } from '../../../utils/array'
|
|
11
10
|
import { isFunction, isUndefinedOrNull } from '../../../utils/inspect'
|
|
12
11
|
import { makeProp } from '../../../utils/props'
|
|
13
12
|
import { safeVueInstance } from '../../../utils/safe-vue-instance'
|
|
@@ -55,7 +54,7 @@ export const props = {
|
|
|
55
54
|
// It should be `initialSortDirection` as it is a bit misleading
|
|
56
55
|
// (not to mention it screws up the ARIA label on the headers)
|
|
57
56
|
sortDirection: makeProp(PROP_TYPE_STRING, SORT_DIRECTION_ASC, value => {
|
|
58
|
-
return
|
|
57
|
+
return SORT_DIRECTIONS.includes(value)
|
|
59
58
|
}),
|
|
60
59
|
// Place the sorting icon on the left of the header cells
|
|
61
60
|
sortIconLeft: makeProp(PROP_TYPE_BOOLEAN, false),
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
CODE_UP
|
|
15
15
|
} from '../../../constants/key-codes'
|
|
16
16
|
import { PROP_TYPE_ARRAY_OBJECT_STRING } from '../../../constants/props'
|
|
17
|
-
import {
|
|
17
|
+
import { from as arrayFrom } from '../../../utils/array'
|
|
18
18
|
import { attemptFocus, closest, isActiveElement, isElement } from '../../../utils/dom'
|
|
19
19
|
import { safeVueInstance } from '../../../utils/safe-vue-instance'
|
|
20
20
|
import { stopEvent } from '../../../utils/events'
|
|
@@ -56,7 +56,7 @@ export const tbodyMixin = extend({
|
|
|
56
56
|
const tbody = $refs.tbody ? $refs.tbody.$el || $refs.tbody : null
|
|
57
57
|
const trs = ($refs['item-rows'] || []).map(tr => tr.$el || tr)
|
|
58
58
|
return tbody && tbody.children && tbody.children.length > 0 && trs && trs.length > 0
|
|
59
|
-
? arrayFrom(tbody.children).filter(tr =>
|
|
59
|
+
? arrayFrom(tbody.children).filter(tr => trs.includes(tr))
|
|
60
60
|
: /* istanbul ignore next */ []
|
|
61
61
|
},
|
|
62
62
|
// Returns index of a particular TBODY item TR
|
|
@@ -103,11 +103,11 @@ export const tbodyMixin = extend({
|
|
|
103
103
|
return
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
-
if (
|
|
106
|
+
if ([CODE_ENTER, CODE_SPACE].includes(keyCode)) {
|
|
107
107
|
// Emulated click for keyboard users, transfer to click handler
|
|
108
108
|
stopEvent(event)
|
|
109
109
|
this.onTBodyRowClicked(event)
|
|
110
|
-
} else if (
|
|
110
|
+
} else if ([CODE_UP, CODE_DOWN, CODE_HOME, CODE_END].includes(keyCode)) {
|
|
111
111
|
// Keyboard navigation
|
|
112
112
|
const rowIndex = this.getTbodyTrIndex(target)
|
|
113
113
|
if (rowIndex > -1) {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { arrayIncludes } from '../../../utils/array'
|
|
2
1
|
import { isArray, isFunction } from '../../../utils/inspect'
|
|
3
2
|
import { clone, keys, pick } from '../../../utils/object'
|
|
4
3
|
import { IGNORED_FIELD_KEYS } from './constants'
|
|
@@ -31,8 +30,8 @@ export const sanitizeRow = (row, ignoreFields, includeFields, fieldsObj = {}) =>
|
|
|
31
30
|
const allowedKeys = keys(formattedRow).filter(
|
|
32
31
|
key =>
|
|
33
32
|
!IGNORED_FIELD_KEYS[key] &&
|
|
34
|
-
!(isArray(ignoreFields) && ignoreFields.length > 0 &&
|
|
35
|
-
!(isArray(includeFields) && includeFields.length > 0 && !
|
|
33
|
+
!(isArray(ignoreFields) && ignoreFields.length > 0 && ignoreFields.includes(key)) &&
|
|
34
|
+
!(isArray(includeFields) && includeFields.length > 0 && !includeFields.includes(key))
|
|
36
35
|
)
|
|
37
36
|
|
|
38
37
|
return pick(formattedRow, allowedKeys)
|
|
@@ -20,9 +20,10 @@ import {
|
|
|
20
20
|
CODE_UP
|
|
21
21
|
} from '../../constants/key-codes'
|
|
22
22
|
import {
|
|
23
|
-
|
|
23
|
+
PROP_TYPE_ARRAY,
|
|
24
24
|
PROP_TYPE_BOOLEAN,
|
|
25
25
|
PROP_TYPE_NUMBER,
|
|
26
|
+
PROP_TYPE_OBJECT,
|
|
26
27
|
PROP_TYPE_STRING
|
|
27
28
|
} from '../../constants/props'
|
|
28
29
|
import {
|
|
@@ -45,7 +46,6 @@ import { makeModelMixin } from '../../utils/model'
|
|
|
45
46
|
import { toInteger } from '../../utils/number'
|
|
46
47
|
import { sortKeys } from '../../utils/object'
|
|
47
48
|
import { observeDom } from '../../utils/observe-dom'
|
|
48
|
-
import { makeProp } from '../../utils/props'
|
|
49
49
|
import { stableSort } from '../../utils/stable-sort'
|
|
50
50
|
import { idMixin, props as idProps } from '../../mixins/id'
|
|
51
51
|
import { normalizeSlotMixin } from '../../mixins/normalize-slot'
|
|
@@ -76,14 +76,41 @@ const BVTabButton = /*#__PURE__*/ extend({
|
|
|
76
76
|
}
|
|
77
77
|
},
|
|
78
78
|
props: {
|
|
79
|
-
controls:
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
79
|
+
controls: {
|
|
80
|
+
type: PROP_TYPE_STRING,
|
|
81
|
+
required: false,
|
|
82
|
+
default: undefined
|
|
83
|
+
},
|
|
84
|
+
id: {
|
|
85
|
+
type: PROP_TYPE_STRING,
|
|
86
|
+
required: false,
|
|
87
|
+
default: undefined
|
|
88
|
+
},
|
|
89
|
+
noKeyNav: {
|
|
90
|
+
type: PROP_TYPE_BOOLEAN,
|
|
91
|
+
required: false,
|
|
92
|
+
default: false
|
|
93
|
+
},
|
|
94
|
+
posInSet: {
|
|
95
|
+
type: PROP_TYPE_NUMBER,
|
|
96
|
+
required: false,
|
|
97
|
+
default: undefined
|
|
98
|
+
},
|
|
99
|
+
setSize: {
|
|
100
|
+
type: PROP_TYPE_NUMBER,
|
|
101
|
+
required: false,
|
|
102
|
+
default: undefined
|
|
103
|
+
},
|
|
84
104
|
// Reference to the child <b-tab> instance
|
|
85
|
-
tab:
|
|
86
|
-
|
|
105
|
+
tab: {
|
|
106
|
+
required: false,
|
|
107
|
+
default: undefined
|
|
108
|
+
},
|
|
109
|
+
tabIndex: {
|
|
110
|
+
type: PROP_TYPE_NUMBER,
|
|
111
|
+
required: false,
|
|
112
|
+
default: undefined
|
|
113
|
+
}
|
|
87
114
|
},
|
|
88
115
|
computed: {
|
|
89
116
|
bvTabs() {
|
|
@@ -188,11 +215,31 @@ const BVTabButton = /*#__PURE__*/ extend({
|
|
|
188
215
|
|
|
189
216
|
// --- Props ---
|
|
190
217
|
const navProps = {
|
|
191
|
-
align:
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
218
|
+
align: {
|
|
219
|
+
type: PROP_TYPE_STRING,
|
|
220
|
+
required: false,
|
|
221
|
+
default: undefined
|
|
222
|
+
},
|
|
223
|
+
fill: {
|
|
224
|
+
type: PROP_TYPE_BOOLEAN,
|
|
225
|
+
required: false,
|
|
226
|
+
default: false
|
|
227
|
+
},
|
|
228
|
+
justified: {
|
|
229
|
+
type: PROP_TYPE_BOOLEAN,
|
|
230
|
+
required: false,
|
|
231
|
+
default: false
|
|
232
|
+
},
|
|
233
|
+
pills: {
|
|
234
|
+
type: PROP_TYPE_BOOLEAN,
|
|
235
|
+
required: false,
|
|
236
|
+
default: false
|
|
237
|
+
},
|
|
238
|
+
small: {
|
|
239
|
+
type: PROP_TYPE_BOOLEAN,
|
|
240
|
+
required: false,
|
|
241
|
+
default: false
|
|
242
|
+
}
|
|
196
243
|
}
|
|
197
244
|
|
|
198
245
|
export const props = sortKeys({
|
|
@@ -200,21 +247,65 @@ export const props = sortKeys({
|
|
|
200
247
|
...modelProps,
|
|
201
248
|
...navProps,
|
|
202
249
|
// Only applied to the currently active `li`
|
|
203
|
-
activeNavItemClass:
|
|
250
|
+
activeNavItemClass: {
|
|
251
|
+
type: [PROP_TYPE_ARRAY, PROP_TYPE_OBJECT, PROP_TYPE_STRING],
|
|
252
|
+
required: false,
|
|
253
|
+
default: undefined
|
|
254
|
+
},
|
|
204
255
|
// Only applied to the currently active `<b-tab>`
|
|
205
256
|
// This prop is sniffed by the `<b-tab>` child
|
|
206
|
-
activeTabClass:
|
|
207
|
-
|
|
257
|
+
activeTabClass: {
|
|
258
|
+
type: [PROP_TYPE_ARRAY, PROP_TYPE_OBJECT, PROP_TYPE_STRING],
|
|
259
|
+
required: false,
|
|
260
|
+
default: undefined
|
|
261
|
+
},
|
|
262
|
+
contentClass: {
|
|
263
|
+
type: [PROP_TYPE_ARRAY, PROP_TYPE_OBJECT, PROP_TYPE_STRING],
|
|
264
|
+
required: false,
|
|
265
|
+
default: undefined
|
|
266
|
+
},
|
|
208
267
|
// Synonym for 'bottom'
|
|
209
|
-
end:
|
|
268
|
+
end: {
|
|
269
|
+
type: PROP_TYPE_BOOLEAN,
|
|
270
|
+
required: false,
|
|
271
|
+
default: false
|
|
272
|
+
},
|
|
210
273
|
// This prop is sniffed by the `<b-tab>` child
|
|
211
|
-
lazy:
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
274
|
+
lazy: {
|
|
275
|
+
type: PROP_TYPE_BOOLEAN,
|
|
276
|
+
required: false,
|
|
277
|
+
default: false
|
|
278
|
+
},
|
|
279
|
+
navClass: {
|
|
280
|
+
type: [PROP_TYPE_ARRAY, PROP_TYPE_OBJECT, PROP_TYPE_STRING],
|
|
281
|
+
required: false,
|
|
282
|
+
default: undefined
|
|
283
|
+
},
|
|
284
|
+
navWrapperClass: {
|
|
285
|
+
type: [PROP_TYPE_ARRAY, PROP_TYPE_OBJECT, PROP_TYPE_STRING],
|
|
286
|
+
required: false,
|
|
287
|
+
default: undefined
|
|
288
|
+
},
|
|
289
|
+
noFade: {
|
|
290
|
+
type: PROP_TYPE_BOOLEAN,
|
|
291
|
+
required: false,
|
|
292
|
+
default: false
|
|
293
|
+
},
|
|
294
|
+
noKeyNav: {
|
|
295
|
+
type: PROP_TYPE_BOOLEAN,
|
|
296
|
+
required: false,
|
|
297
|
+
default: false
|
|
298
|
+
},
|
|
299
|
+
noNavStyle: {
|
|
300
|
+
type: PROP_TYPE_BOOLEAN,
|
|
301
|
+
required: false,
|
|
302
|
+
default: false
|
|
303
|
+
},
|
|
304
|
+
tag: {
|
|
305
|
+
type: PROP_TYPE_STRING,
|
|
306
|
+
required: false,
|
|
307
|
+
default: 'div'
|
|
308
|
+
}
|
|
218
309
|
})
|
|
219
310
|
|
|
220
311
|
// --- Main component ---
|
|
@@ -64,7 +64,7 @@ const parseBindings = (bindings, vnode) => /* istanbul ignore next: not easy to
|
|
|
64
64
|
html: false,
|
|
65
65
|
interactive: true,
|
|
66
66
|
disabled: false,
|
|
67
|
-
delay: TOOLTIP_DELAY,
|
|
67
|
+
delay: { ...TOOLTIP_DELAY },
|
|
68
68
|
boundary: 'scrollParent',
|
|
69
69
|
boundaryPadding: 5,
|
|
70
70
|
variant: undefined,
|