@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gitlab/ui",
3
- "version": "131.3.2",
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.4.27",
136
+ "autoprefixer": "10.5.0",
136
137
  "axe-playwright": "^2.2.2",
137
138
  "babel-loader": "^9.2.1",
138
- "cypress": "15.13.1",
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 { isEvent } from '../../../vendor/bootstrap-vue/src/utils/inspect';
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 = isEvent(event);
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
- attemptFocus(this.$el);
292
+ this.$el.focus();
296
293
  },
297
294
  blur() {
298
- attemptBlur(this.$el);
295
+ this.$el.blur();
299
296
  },
300
297
  },
301
298
  };
@@ -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
- PROP_TYPE_ARRAY_OBJECT_STRING,
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: makeProp(PROP_TYPE_STRING),
108
- autoFocusButton: makeProp(
109
- PROP_TYPE_STRING,
110
- null,
111
- /* istanbul ignore next */ value => {
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: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING),
116
- busy: makeProp(PROP_TYPE_BOOLEAN, false),
117
- buttonSize: makeProp(PROP_TYPE_STRING),
118
- cancelDisabled: makeProp(PROP_TYPE_BOOLEAN, false),
119
- cancelTitle: makeProp(PROP_TYPE_STRING, 'Cancel'),
120
- cancelTitleHtml: makeProp(PROP_TYPE_STRING),
121
- cancelVariant: makeProp(PROP_TYPE_STRING, 'secondary'),
122
- centered: makeProp(PROP_TYPE_BOOLEAN, false),
123
- contentClass: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING),
124
- dialogClass: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING),
125
- footerClass: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING),
126
- footerTag: makeProp(PROP_TYPE_STRING, 'footer'),
127
- headerClass: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING),
128
- headerCloseContent: makeProp(PROP_TYPE_STRING, '&times;'),
129
- headerCloseLabel: makeProp(PROP_TYPE_STRING, 'Close'),
130
- headerTag: makeProp(PROP_TYPE_STRING, 'header'),
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: '&times;'
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: makeProp(PROP_TYPE_BOOLEAN, false),
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: makeProp(PROP_TYPE_BOOLEAN, false),
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: makeProp(PROP_TYPE_BOOLEAN, false),
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: makeProp(PROP_TYPE_BOOLEAN, false),
139
- ignoreEnforceFocusSelector: makeProp(PROP_TYPE_ARRAY_STRING),
140
- lazy: makeProp(PROP_TYPE_BOOLEAN, false),
141
- modalClass: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING),
142
- noCloseOnBackdrop: makeProp(PROP_TYPE_BOOLEAN, false),
143
- noCloseOnEsc: makeProp(PROP_TYPE_BOOLEAN, false),
144
- noEnforceFocus: makeProp(PROP_TYPE_BOOLEAN, false),
145
- noFade: makeProp(PROP_TYPE_BOOLEAN, false),
146
- noStacking: makeProp(PROP_TYPE_BOOLEAN, false),
147
- okDisabled: makeProp(PROP_TYPE_BOOLEAN, false),
148
- okOnly: makeProp(PROP_TYPE_BOOLEAN, false),
149
- okTitle: makeProp(PROP_TYPE_STRING, 'OK'),
150
- okTitleHtml: makeProp(PROP_TYPE_STRING),
151
- okVariant: makeProp(PROP_TYPE_STRING, 'primary'),
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: makeProp([HTMLElement, PROP_TYPE_OBJECT, PROP_TYPE_STRING]),
154
- scrollable: makeProp(PROP_TYPE_BOOLEAN, false),
155
- size: makeProp(PROP_TYPE_STRING, 'md'),
156
- static: makeProp(PROP_TYPE_BOOLEAN, false),
157
- title: makeProp(PROP_TYPE_STRING),
158
- titleClass: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING),
159
- titleHtml: makeProp(PROP_TYPE_STRING),
160
- titleTag: makeProp(PROP_TYPE_STRING, 'h5')
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
- PROP_TYPE_NUMBER_STRING
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: makeProp([...PROP_TYPE_ARRAY_OBJECT_STRING, PROP_TYPE_REG_EXP]),
32
- filterDebounce: makeProp(PROP_TYPE_NUMBER_STRING, 0, value => {
33
- return RX_DIGITS.test(String(value))
34
- }),
35
- filterFunction: makeProp(PROP_TYPE_FUNCTION),
36
- filterIgnoredFields: makeProp(PROP_TYPE_ARRAY, []),
37
- filterIncludedFields: makeProp(PROP_TYPE_ARRAY, [])
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 { arrayIncludes, createArray } from '../../../utils/array'
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 arrayIncludes(SELECT_MODES, value)
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 && arrayIncludes(['range', 'multi'], this.selectMode)
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 arrayIncludes(SORT_DIRECTIONS, value)
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 { arrayIncludes, from as arrayFrom } from '../../../utils/array'
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 => arrayIncludes(trs, 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 (arrayIncludes([CODE_ENTER, CODE_SPACE], keyCode)) {
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 (arrayIncludes([CODE_UP, CODE_DOWN, CODE_HOME, CODE_END], keyCode)) {
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 && arrayIncludes(ignoreFields, key)) &&
35
- !(isArray(includeFields) && includeFields.length > 0 && !arrayIncludes(includeFields, key))
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
- PROP_TYPE_ARRAY_OBJECT_STRING,
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: makeProp(PROP_TYPE_STRING),
80
- id: makeProp(PROP_TYPE_STRING),
81
- noKeyNav: makeProp(PROP_TYPE_BOOLEAN, false),
82
- posInSet: makeProp(PROP_TYPE_NUMBER),
83
- setSize: makeProp(PROP_TYPE_NUMBER),
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: makeProp(),
86
- tabIndex: makeProp(PROP_TYPE_NUMBER)
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: makeProp(PROP_TYPE_STRING),
192
- fill: makeProp(PROP_TYPE_BOOLEAN, false),
193
- justified: makeProp(PROP_TYPE_BOOLEAN, false),
194
- pills: makeProp(PROP_TYPE_BOOLEAN, false),
195
- small: makeProp(PROP_TYPE_BOOLEAN, false)
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: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING),
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: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING),
207
- contentClass: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING),
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: makeProp(PROP_TYPE_BOOLEAN, false),
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: makeProp(PROP_TYPE_BOOLEAN, false),
212
- navClass: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING),
213
- navWrapperClass: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING),
214
- noFade: makeProp(PROP_TYPE_BOOLEAN, false),
215
- noKeyNav: makeProp(PROP_TYPE_BOOLEAN, false),
216
- noNavStyle: makeProp(PROP_TYPE_BOOLEAN, false),
217
- tag: makeProp(PROP_TYPE_STRING, 'div')
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 ---
@@ -4,7 +4,7 @@ export const PROP_NAME = '$bvConfig'
4
4
  export const DEFAULT_BREAKPOINT = ['xs', 'sm', 'md', 'lg', 'xl']
5
5
 
6
6
  // in milliseconds
7
- export const TOOLTIP_DELAY = {
7
+ export const TOOLTIP_DELAY = Object.freeze({
8
8
  show: 500,
9
9
  hide: 0
10
- }
10
+ })
@@ -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,