@gitlab/ui 131.1.0 → 131.3.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.
Files changed (48) hide show
  1. package/dist/components/base/filtered_search/filtered_search.js +15 -4
  2. package/dist/components/base/filtered_search/filtered_search_term.js +1 -1
  3. package/dist/components/base/filtered_search/filtered_search_token_segment.js +1 -1
  4. package/dist/components/base/form/form_checkbox/form_checkbox.js +1 -2
  5. package/dist/components/base/form/form_checkbox/form_checkbox_group.js +1 -1
  6. package/dist/components/base/form/form_radio/form_radio.js +1 -1
  7. package/dist/components/base/form/form_radio_group/form_radio_group.js +1 -1
  8. package/dist/index.css +1 -1
  9. package/dist/index.css.map +1 -1
  10. package/dist/utils/equality_utils.js +84 -0
  11. package/dist/vendor/bootstrap-vue/src/components/button/button-close.js +20 -5
  12. package/dist/vendor/bootstrap-vue/src/components/button/button.js +36 -8
  13. package/dist/vendor/bootstrap-vue/src/components/dropdown/dropdown-item.js +12 -4
  14. package/dist/vendor/bootstrap-vue/src/components/dropdown/dropdown-text.js +16 -5
  15. package/dist/vendor/bootstrap-vue/src/components/dropdown/dropdown.js +99 -23
  16. package/dist/vendor/bootstrap-vue/src/components/form/form-text.js +20 -5
  17. package/dist/vendor/bootstrap-vue/src/components/form/form.js +20 -5
  18. package/dist/vendor/bootstrap-vue/src/components/layout/form-row.js +5 -2
  19. package/dist/vendor/bootstrap-vue/src/components/table/tbody.js +10 -3
  20. package/dist/vendor/bootstrap-vue/src/components/table/td.js +28 -7
  21. package/dist/vendor/bootstrap-vue/src/components/table/tfoot.js +5 -2
  22. package/dist/vendor/bootstrap-vue/src/components/table/thead.js +5 -2
  23. package/dist/vendor/bootstrap-vue/src/components/table/tr.js +5 -2
  24. package/dist/vendor/bootstrap-vue/src/components/tabs/tab.js +51 -12
  25. package/package.json +9 -9
  26. package/src/components/base/filtered_search/filtered_search.vue +16 -4
  27. package/src/components/base/filtered_search/filtered_search_term.vue +1 -1
  28. package/src/components/base/filtered_search/filtered_search_token_segment.vue +2 -1
  29. package/src/components/base/form/form_checkbox/form_checkbox.vue +1 -2
  30. package/src/components/base/form/form_checkbox/form_checkbox_group.vue +1 -1
  31. package/src/components/base/form/form_radio/form_radio.vue +1 -1
  32. package/src/components/base/form/form_radio_group/form_radio_group.vue +1 -1
  33. package/src/components/base/table/table.scss +8 -0
  34. package/src/utils/equality_utils.js +82 -0
  35. package/src/vendor/bootstrap-vue/src/components/button/button-close.js +20 -5
  36. package/src/vendor/bootstrap-vue/src/components/button/button.js +36 -8
  37. package/src/vendor/bootstrap-vue/src/components/dropdown/dropdown-item.js +12 -4
  38. package/src/vendor/bootstrap-vue/src/components/dropdown/dropdown-text.js +16 -5
  39. package/src/vendor/bootstrap-vue/src/components/dropdown/dropdown.js +99 -24
  40. package/src/vendor/bootstrap-vue/src/components/form/form-text.js +20 -5
  41. package/src/vendor/bootstrap-vue/src/components/form/form.js +20 -5
  42. package/src/vendor/bootstrap-vue/src/components/layout/form-row.js +5 -2
  43. package/src/vendor/bootstrap-vue/src/components/table/tbody.js +10 -3
  44. package/src/vendor/bootstrap-vue/src/components/table/td.js +28 -7
  45. package/src/vendor/bootstrap-vue/src/components/table/tfoot.js +5 -2
  46. package/src/vendor/bootstrap-vue/src/components/table/thead.js +5 -2
  47. package/src/vendor/bootstrap-vue/src/components/table/tr.js +5 -2
  48. package/src/vendor/bootstrap-vue/src/components/tabs/tab.js +51 -12
@@ -1,10 +1,9 @@
1
1
  import { extend } from '../../vue';
2
2
  import { NAME_TAB } from '../../constants/components';
3
3
  import { MODEL_EVENT_NAME_PREFIX } from '../../constants/events';
4
- import { PROP_TYPE_BOOLEAN, PROP_TYPE_STRING, PROP_TYPE_ARRAY_OBJECT_STRING, PROP_TYPE_OBJECT } from '../../constants/props';
4
+ import { PROP_TYPE_BOOLEAN, PROP_TYPE_STRING, PROP_TYPE_ARRAY, PROP_TYPE_OBJECT } from '../../constants/props';
5
5
  import { SLOT_NAME_TITLE } from '../../constants/slots';
6
6
  import { sortKeys } from '../../utils/object';
7
- import { makeProp } from '../../utils/props';
8
7
  import { props as props$1, idMixin } from '../../mixins/id';
9
8
  import { normalizeSlotMixin } from '../../mixins/normalize-slot';
10
9
  import { BVTransition } from '../transition/bv-transition';
@@ -18,18 +17,58 @@ const MODEL_EVENT_NAME_ACTIVE = MODEL_EVENT_NAME_PREFIX + MODEL_PROP_NAME_ACTIVE
18
17
 
19
18
  const props = sortKeys({
20
19
  ...props$1,
21
- [MODEL_PROP_NAME_ACTIVE]: makeProp(PROP_TYPE_BOOLEAN, false),
22
- buttonId: makeProp(PROP_TYPE_STRING),
23
- disabled: makeProp(PROP_TYPE_BOOLEAN, false),
24
- lazy: makeProp(PROP_TYPE_BOOLEAN, false),
25
- noBody: makeProp(PROP_TYPE_BOOLEAN, false),
26
- tag: makeProp(PROP_TYPE_STRING, 'div'),
27
- title: makeProp(PROP_TYPE_STRING),
20
+ [MODEL_PROP_NAME_ACTIVE]: {
21
+ type: PROP_TYPE_BOOLEAN,
22
+ required: false,
23
+ default: false
24
+ },
25
+ buttonId: {
26
+ type: PROP_TYPE_STRING,
27
+ required: false,
28
+ default: undefined
29
+ },
30
+ disabled: {
31
+ type: PROP_TYPE_BOOLEAN,
32
+ required: false,
33
+ default: false
34
+ },
35
+ lazy: {
36
+ type: PROP_TYPE_BOOLEAN,
37
+ required: false,
38
+ default: false
39
+ },
40
+ noBody: {
41
+ type: PROP_TYPE_BOOLEAN,
42
+ required: false,
43
+ default: false
44
+ },
45
+ tag: {
46
+ type: PROP_TYPE_STRING,
47
+ required: false,
48
+ default: 'div'
49
+ },
50
+ title: {
51
+ type: PROP_TYPE_STRING,
52
+ required: false,
53
+ default: undefined
54
+ },
28
55
  // Sniffed by `<b-tabs>` and added to nav `li.nav-item`
29
- titleItemClass: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING),
30
- titleLinkAttributes: makeProp(PROP_TYPE_OBJECT),
56
+ titleItemClass: {
57
+ type: [PROP_TYPE_ARRAY, PROP_TYPE_OBJECT, PROP_TYPE_STRING],
58
+ required: false,
59
+ default: undefined
60
+ },
61
+ titleLinkAttributes: {
62
+ type: PROP_TYPE_OBJECT,
63
+ required: false,
64
+ default: undefined
65
+ },
31
66
  // Sniffed by `<b-tabs>` and added to nav `a.nav-link`
32
- titleLinkClass: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING)
67
+ titleLinkClass: {
68
+ type: [PROP_TYPE_ARRAY, PROP_TYPE_OBJECT, PROP_TYPE_STRING],
69
+ required: false,
70
+ default: undefined
71
+ }
33
72
  });
34
73
 
35
74
  // --- Main component ---
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gitlab/ui",
3
- "version": "131.1.0",
3
+ "version": "131.3.0",
4
4
  "description": "GitLab UI Components",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -72,7 +72,7 @@
72
72
  "echarts": "^5.6.0",
73
73
  "gridstack": "^12.4.2",
74
74
  "iframe-resizer": "^4.4.5",
75
- "lodash-es": "^4.17.23",
75
+ "lodash-es": "^4.18.1",
76
76
  "popper.js": "^1.16.1",
77
77
  "portal-vue": "2.1.7",
78
78
  "vue-functional-data-merge": "^3.1.0",
@@ -101,7 +101,7 @@
101
101
  "@babel/preset-env": "^7.29.2",
102
102
  "@babel/preset-react": "^7.28.5",
103
103
  "@cypress/grep": "^4.1.1",
104
- "@figma/code-connect": "^1.4.2",
104
+ "@figma/code-connect": "^1.4.3",
105
105
  "@gitlab/fonts": "^1.3.1",
106
106
  "@gitlab/svgs": "*",
107
107
  "@jest/test-sequencer": "30.3.0",
@@ -122,9 +122,9 @@
122
122
  "@storybook/vue3": "^7.6.24",
123
123
  "@storybook/vue3-webpack5": "^7.6.24",
124
124
  "@types/jest-image-snapshot": "^6.4.1",
125
- "@vue/compat": "3.5.30",
126
- "@vue/compiler-sfc": "3.5.30",
127
- "@vue/server-renderer": "3.5.30",
125
+ "@vue/compat": "3.5.32",
126
+ "@vue/compiler-sfc": "3.5.32",
127
+ "@vue/server-renderer": "3.5.32",
128
128
  "@vue/test-utils": "1.3.6",
129
129
  "@vue/test-utils-vue3": "npm:@vue/test-utils@^2.4.6",
130
130
  "@vue/vue2-jest": "29.2.6",
@@ -150,8 +150,8 @@
150
150
  "mockdate": "^3.0.5",
151
151
  "module-alias": "^2.3.4",
152
152
  "pikaday": "^1.8.0",
153
- "playwright": "^1.58.2",
154
- "playwright-core": "^1.58.2",
153
+ "playwright": "^1.59.1",
154
+ "playwright-core": "^1.59.1",
155
155
  "postcss": "8.5.8",
156
156
  "postcss-loader": "8.2.1",
157
157
  "postcss-scss": "4.0.9",
@@ -163,7 +163,7 @@
163
163
  "rollup-plugin-string": "^3.0.0",
164
164
  "rollup-plugin-svg": "^2.0.0",
165
165
  "rollup-plugin-vue": "^5.1.9",
166
- "sass": "^1.98.0",
166
+ "sass": "^1.99.0",
167
167
  "sass-loader": "^10.5.2",
168
168
  "sass-true": "^9",
169
169
  "start-server-and-test": "^2.1.5",
@@ -349,10 +349,15 @@ export default {
349
349
  // Preserve the active token's active status (it shifted down one index)
350
350
  this.activeTokenIdx -= 1;
351
351
  } else if (idx === this.activeTokenIdx) {
352
- // User destroyed the active token; don't activate another one.
353
- this.activeTokenIdx = null;
352
+ // User destroyed the active token; activate the last token so focus
353
+ // moves to the search input rather than being lost.
354
+ this.activeTokenIdx = this.lastTokenIdx;
355
+ } else if (this.activeTokenIdx === null) {
356
+ // No token was active (e.g. clicking the X button on an inactive token);
357
+ // activate the last token so focus moves to the search input.
358
+ this.activeTokenIdx = this.lastTokenIdx;
354
359
  }
355
- // Do nothing if there was no active token, or if idx > this.activeTokenIdx,
360
+ // Do nothing if idx > this.activeTokenIdx,
356
361
  // to preserve the active state of the remaining tokens.
357
362
  },
358
363
 
@@ -388,6 +393,13 @@ export default {
388
393
  }
389
394
  },
390
395
 
396
+ onClear() {
397
+ this.$nextTick(() => {
398
+ this.activeTokenIdx = this.lastTokenIdx;
399
+ this.$emit('clear');
400
+ });
401
+ },
402
+
391
403
  submit() {
392
404
  /**
393
405
  * Emitted when search is submitted
@@ -412,7 +424,7 @@ export default {
412
424
  @submit="submit"
413
425
  @input="applyNewValue"
414
426
  @history-item-selected="$emit('history-item-selected', $event)"
415
- @clear="$emit('clear')"
427
+ @clear="onClear"
416
428
  @clear-history="$emit('clear-history')"
417
429
  >
418
430
  <template #history-item="slotScope">
@@ -94,7 +94,7 @@ export default {
94
94
  },
95
95
  computed: {
96
96
  showInput() {
97
- return this.termsAsTokens() || Boolean(this.placeholder);
97
+ return this.termsAsTokens() || Boolean(this.placeholder) || this.isLastToken;
98
98
  },
99
99
  showToken() {
100
100
  return this.termsAsTokens() && Boolean(this.value.data);
@@ -470,7 +470,8 @@ export default {
470
470
  :key="`operator-${_uid}`"
471
471
  ref="suggestions"
472
472
  role="list"
473
- tabindex="0"
473
+ tabindex="-1"
474
+ data-testid="filtered-search-suggestion-list"
474
475
  :initial-value="defaultSuggestedValue"
475
476
  @suggestion="applySuggestion"
476
477
  >
@@ -1,7 +1,6 @@
1
1
  <script>
2
2
  import { uniqueId, isBoolean } from 'lodash-es';
3
- import { looseEqual } from '../../../../vendor/bootstrap-vue/src/utils/loose-equal';
4
- import { looseIndexOf } from '../../../../vendor/bootstrap-vue/src/utils/loose-index-of';
3
+ import { looseEqual, looseIndexOf } from '../../../../utils/equality_utils';
5
4
 
6
5
  export default {
7
6
  name: 'GlFormCheckbox',
@@ -1,6 +1,6 @@
1
1
  <script>
2
2
  import { uniqueId, isBoolean, omit, pick } from 'lodash-es';
3
- import { looseEqual } from '../../../../vendor/bootstrap-vue/src/utils/loose-equal';
3
+ import { looseEqual } from '../../../../utils/equality_utils';
4
4
  import { formOptionsMixin } from '../../../../vendor/bootstrap-vue/src/mixins/form-options';
5
5
  import { SafeHtmlDirective as SafeHtml } from '../../../../directives/safe_html/safe_html';
6
6
  import GlFormCheckbox from './form_checkbox.vue';
@@ -1,6 +1,6 @@
1
1
  <script>
2
2
  import { isBoolean, uniqueId } from 'lodash-es';
3
- import { looseEqual } from '../../../../vendor/bootstrap-vue/src/utils/loose-equal';
3
+ import { looseEqual } from '../../../../utils/equality_utils';
4
4
 
5
5
  export default {
6
6
  name: 'GlFormRadio',
@@ -1,6 +1,6 @@
1
1
  <script>
2
2
  import { uniqueId, isBoolean, omit, pick } from 'lodash-es';
3
- import { looseEqual } from '../../../../vendor/bootstrap-vue/src/utils/loose-equal';
3
+ import { looseEqual } from '../../../../utils/equality_utils';
4
4
  import { formOptionsMixin } from '../../../../vendor/bootstrap-vue/src/mixins/form-options';
5
5
  import { SafeHtmlDirective as SafeHtml } from '../../../../directives/safe_html/safe_html';
6
6
  import GlFormRadio from '../form_radio/form_radio.vue';
@@ -23,6 +23,14 @@ table.gl-table {
23
23
  }
24
24
  }
25
25
 
26
+ &.table-borderless {
27
+ tr {
28
+ td {
29
+ @apply gl-border-b-0;
30
+ }
31
+ }
32
+ }
33
+
26
34
  thead tr th {
27
35
  @apply gl-font-bold gl-text-heading;
28
36
 
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Performs a deep, type-coercing equality check between two values.
3
+ *
4
+ * Unlike strict equality (`===`) or lodash's `isEqual`, this function:
5
+ * - Compares objects and arrays by structure, not reference
6
+ * - Coerces types before comparing primitives (e.g. `123` equals `'123'`)
7
+ * - Compares Date objects by timestamp
8
+ * - Compares File objects by inherited properties (name, size, type, lastModified)
9
+ *
10
+ * Used in form components (radio, checkbox) to detect meaningful value changes
11
+ * in watchers, avoiding redundant event emissions when values are loosely equivalent.
12
+ *
13
+ * @param {*} a - First value to compare
14
+ * @param {*} b - Second value to compare
15
+ * @returns {boolean} Whether the two values are loosely equal
16
+ */
17
+ export function looseEqual(a, b) {
18
+ if (a === b) {
19
+ return true;
20
+ }
21
+ let aValidType = a instanceof Date;
22
+ let bValidType = b instanceof Date;
23
+ if (aValidType || bValidType) {
24
+ return aValidType && bValidType ? a.getTime() === b.getTime() : false;
25
+ }
26
+ aValidType = Array.isArray(a);
27
+ bValidType = Array.isArray(b);
28
+ if (aValidType || bValidType) {
29
+ if (!aValidType || !bValidType || a.length !== b.length) {
30
+ return false;
31
+ }
32
+ // Compare arrays element by element
33
+ // Uses a for loop to handle sparse arrays (array.every doesn't handle sparse)
34
+ let equal = true;
35
+ for (let i = 0; equal && i < a.length; i += 1) {
36
+ equal = looseEqual(a[i], b[i]);
37
+ }
38
+ return equal;
39
+ }
40
+ aValidType = a !== null && typeof a === 'object';
41
+ bValidType = b !== null && typeof b === 'object';
42
+ if (aValidType || bValidType) {
43
+ if (!aValidType || !bValidType) {
44
+ return false;
45
+ }
46
+ const aKeysCount = Object.keys(a).length;
47
+ const bKeysCount = Object.keys(b).length;
48
+ if (aKeysCount !== bKeysCount) {
49
+ return false;
50
+ }
51
+ // Intentionally iterates inherited properties to compare complex types
52
+ // like File objects where properties are on the prototype
53
+ // eslint-disable-next-line guard-for-in
54
+ for (const key in a) {
55
+ const aHasKey = Object.prototype.hasOwnProperty.call(a, key);
56
+ const bHasKey = Object.prototype.hasOwnProperty.call(b, key);
57
+ if ((aHasKey && !bHasKey) || (!aHasKey && bHasKey) || !looseEqual(a[key], b[key])) {
58
+ return false;
59
+ }
60
+ }
61
+ }
62
+ return String(a) === String(b);
63
+ }
64
+
65
+ /**
66
+ * Finds the first index in an array where the element is loosely equal to the given value.
67
+ *
68
+ * Works like `Array.prototype.indexOf`, but uses {@link looseEqual} for comparison
69
+ * instead of strict equality.
70
+ *
71
+ * @param {Array} array - The array to search
72
+ * @param {*} value - The value to find
73
+ * @returns {number} The index of the first loosely matching element, or -1 if not found
74
+ */
75
+ export function looseIndexOf(array, value) {
76
+ for (let i = 0; i < array.length; i += 1) {
77
+ if (looseEqual(array[i], value)) {
78
+ return i;
79
+ }
80
+ }
81
+ return -1;
82
+ }
@@ -4,16 +4,31 @@ import { PROP_TYPE_BOOLEAN, PROP_TYPE_STRING } from '../../constants/props'
4
4
  import { SLOT_NAME_DEFAULT } from '../../constants/slots'
5
5
  import { stopEvent } from '../../utils/events'
6
6
  import { isEvent } from '../../utils/inspect'
7
- import { makeProp } from '../../utils/props'
8
7
  import { hasNormalizedSlot, normalizeSlot } from '../../utils/normalize-slot'
9
8
 
10
9
  // --- Props ---
11
10
 
12
11
  export const props = {
13
- ariaLabel: makeProp(PROP_TYPE_STRING, 'Close'),
14
- content: makeProp(PROP_TYPE_STRING, '&times;'),
15
- disabled: makeProp(PROP_TYPE_BOOLEAN, false),
16
- textVariant: makeProp(PROP_TYPE_STRING)
12
+ ariaLabel: {
13
+ type: PROP_TYPE_STRING,
14
+ required: false,
15
+ default: 'Close'
16
+ },
17
+ content: {
18
+ type: PROP_TYPE_STRING,
19
+ required: false,
20
+ default: '&times;'
21
+ },
22
+ disabled: {
23
+ type: PROP_TYPE_BOOLEAN,
24
+ required: false,
25
+ default: false
26
+ },
27
+ textVariant: {
28
+ type: PROP_TYPE_STRING,
29
+ required: false,
30
+ default: undefined
31
+ }
17
32
  }
18
33
 
19
34
  // --- Main component ---
@@ -7,7 +7,7 @@ import { addClass, isTag, removeClass } from '../../utils/dom'
7
7
  import { stopEvent } from '../../utils/events'
8
8
  import { isBoolean, isEvent, isFunction } from '../../utils/inspect'
9
9
  import { omit, sortKeys } from '../../utils/object'
10
- import { makeProp, pluckProps } from '../../utils/props'
10
+ import { pluckProps } from '../../utils/props'
11
11
  import { isLink as isLinkStrict } from '../../utils/router'
12
12
  import { BLink, props as BLinkProps } from '../link/link'
13
13
 
@@ -19,15 +19,43 @@ delete linkProps.to.default
19
19
 
20
20
  export const props = sortKeys({
21
21
  ...linkProps,
22
- block: makeProp(PROP_TYPE_BOOLEAN, false),
23
- disabled: makeProp(PROP_TYPE_BOOLEAN, false),
22
+ block: {
23
+ type: PROP_TYPE_BOOLEAN,
24
+ required: false,
25
+ default: false
26
+ },
27
+ disabled: {
28
+ type: PROP_TYPE_BOOLEAN,
29
+ required: false,
30
+ default: false
31
+ },
24
32
  // Tri-state: `true`, `false` or `null`
25
33
  // => On, off, not a toggle
26
- pressed: makeProp(PROP_TYPE_BOOLEAN, null),
27
- size: makeProp(PROP_TYPE_STRING),
28
- tag: makeProp(PROP_TYPE_STRING, 'button'),
29
- type: makeProp(PROP_TYPE_STRING, 'button'),
30
- variant: makeProp(PROP_TYPE_STRING, 'secondary')
34
+ pressed: {
35
+ type: PROP_TYPE_BOOLEAN,
36
+ required: false,
37
+ default: null
38
+ },
39
+ size: {
40
+ type: PROP_TYPE_STRING,
41
+ required: false,
42
+ default: undefined
43
+ },
44
+ tag: {
45
+ type: PROP_TYPE_STRING,
46
+ required: false,
47
+ default: 'button'
48
+ },
49
+ type: {
50
+ type: PROP_TYPE_STRING,
51
+ required: false,
52
+ default: 'button'
53
+ },
54
+ variant: {
55
+ type: PROP_TYPE_STRING,
56
+ required: false,
57
+ default: 'secondary'
58
+ }
31
59
  })
32
60
 
33
61
  // --- Helper methods ---
@@ -1,10 +1,10 @@
1
1
  import { extend } from '../../vue'
2
2
  import { NAME_DROPDOWN_ITEM } from '../../constants/components'
3
3
  import { EVENT_NAME_CLICK } from '../../constants/events'
4
- import { PROP_TYPE_ARRAY_OBJECT_STRING, PROP_TYPE_STRING } from '../../constants/props'
4
+ import { PROP_TYPE_ARRAY, PROP_TYPE_OBJECT, PROP_TYPE_STRING } from '../../constants/props'
5
5
  import { requestAF } from '../../utils/dom'
6
6
  import { omit, sortKeys } from '../../utils/object'
7
- import { makeProp, pluckProps } from '../../utils/props'
7
+ import { pluckProps } from '../../utils/props'
8
8
  import { attrsMixin } from '../../mixins/attrs'
9
9
  import { normalizeSlotMixin } from '../../mixins/normalize-slot'
10
10
  import { BLink, props as BLinkProps } from '../link/link'
@@ -15,8 +15,16 @@ const linkProps = omit(BLinkProps, ['event', 'routerTag'])
15
15
 
16
16
  export const props = sortKeys({
17
17
  ...linkProps,
18
- linkClass: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING),
19
- variant: makeProp(PROP_TYPE_STRING)
18
+ linkClass: {
19
+ type: [PROP_TYPE_ARRAY, PROP_TYPE_OBJECT, PROP_TYPE_STRING],
20
+ required: false,
21
+ default: undefined
22
+ },
23
+ variant: {
24
+ type: PROP_TYPE_STRING,
25
+ required: false,
26
+ default: undefined
27
+ }
20
28
  })
21
29
 
22
30
  // --- Main component ---
@@ -1,15 +1,26 @@
1
1
  import { extend, mergeData } from '../../vue'
2
2
  import { NAME_DROPDOWN_TEXT } from '../../constants/components'
3
- import { PROP_TYPE_ARRAY_OBJECT_STRING, PROP_TYPE_STRING } from '../../constants/props'
3
+ import { PROP_TYPE_ARRAY, PROP_TYPE_OBJECT, PROP_TYPE_STRING } from '../../constants/props'
4
4
  import { omit } from '../../utils/object'
5
- import { makeProp } from '../../utils/props'
6
5
 
7
6
  // --- Props ---
8
7
 
9
8
  export const props = {
10
- tag: makeProp(PROP_TYPE_STRING, 'p'),
11
- textClass: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING),
12
- variant: makeProp(PROP_TYPE_STRING)
9
+ tag: {
10
+ type: PROP_TYPE_STRING,
11
+ required: false,
12
+ default: 'p'
13
+ },
14
+ textClass: {
15
+ type: [PROP_TYPE_ARRAY, PROP_TYPE_OBJECT, PROP_TYPE_STRING],
16
+ required: false,
17
+ default: undefined
18
+ },
19
+ variant: {
20
+ type: PROP_TYPE_STRING,
21
+ required: false,
22
+ default: undefined
23
+ }
13
24
  }
14
25
 
15
26
  // --- Main component ---
@@ -1,16 +1,14 @@
1
1
  import { extend } from '../../vue'
2
2
  import { NAME_DROPDOWN } from '../../constants/components'
3
3
  import {
4
- PROP_TYPE_ARRAY_OBJECT_STRING,
4
+ PROP_TYPE_ARRAY,
5
5
  PROP_TYPE_BOOLEAN,
6
6
  PROP_TYPE_OBJECT,
7
- PROP_TYPE_OBJECT_STRING,
8
7
  PROP_TYPE_STRING
9
8
  } from '../../constants/props'
10
9
  import { SLOT_NAME_BUTTON_CONTENT, SLOT_NAME_DEFAULT } from '../../constants/slots'
11
10
  import { arrayIncludes } from '../../utils/array'
12
11
  import { htmlOrText } from '../../utils/html'
13
- import { makeProp } from '../../utils/props'
14
12
  import { toString } from '../../utils/string'
15
13
  import { dropdownMixin, props as dropdownProps } from '../../mixins/dropdown'
16
14
  import { idMixin, props as idProps } from '../../mixins/id'
@@ -23,29 +21,106 @@ import { sortKeys } from '../../utils/object'
23
21
  export const props = sortKeys({
24
22
  ...idProps,
25
23
  ...dropdownProps,
26
- block: makeProp(PROP_TYPE_BOOLEAN, false),
27
- html: makeProp(PROP_TYPE_STRING),
24
+ block: {
25
+ type: PROP_TYPE_BOOLEAN,
26
+ required: false,
27
+ default: false
28
+ },
29
+ html: {
30
+ type: PROP_TYPE_STRING,
31
+ required: false,
32
+ default: undefined
33
+ },
28
34
  // If `true`, only render menu contents when open
29
- lazy: makeProp(PROP_TYPE_BOOLEAN, false),
30
- menuClass: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING),
31
- noCaret: makeProp(PROP_TYPE_BOOLEAN, false),
32
- role: makeProp(PROP_TYPE_STRING, 'menu'),
33
- size: makeProp(PROP_TYPE_STRING),
34
- split: makeProp(PROP_TYPE_BOOLEAN, false),
35
- splitButtonType: makeProp(PROP_TYPE_STRING, 'button', value => {
36
- return arrayIncludes(['button', 'submit', 'reset'], value)
37
- }),
38
- splitClass: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING),
39
- splitHref: makeProp(PROP_TYPE_STRING),
40
- splitTo: makeProp(PROP_TYPE_OBJECT_STRING),
41
- splitVariant: makeProp(PROP_TYPE_STRING),
42
- text: makeProp(PROP_TYPE_STRING),
43
- toggleAttrs: makeProp(PROP_TYPE_OBJECT, {}),
44
- toggleClass: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING),
45
- toggleTag: makeProp(PROP_TYPE_STRING, 'button'),
35
+ lazy: {
36
+ type: PROP_TYPE_BOOLEAN,
37
+ required: false,
38
+ default: false
39
+ },
40
+ menuClass: {
41
+ type: [PROP_TYPE_ARRAY, PROP_TYPE_OBJECT, PROP_TYPE_STRING],
42
+ required: false,
43
+ default: undefined
44
+ },
45
+ noCaret: {
46
+ type: PROP_TYPE_BOOLEAN,
47
+ required: false,
48
+ default: false
49
+ },
50
+ role: {
51
+ type: PROP_TYPE_STRING,
52
+ required: false,
53
+ default: 'menu'
54
+ },
55
+ size: {
56
+ type: PROP_TYPE_STRING,
57
+ required: false,
58
+ default: undefined
59
+ },
60
+ split: {
61
+ type: PROP_TYPE_BOOLEAN,
62
+ required: false,
63
+ default: false
64
+ },
65
+ splitButtonType: {
66
+ type: PROP_TYPE_STRING,
67
+ required: false,
68
+ default: 'button',
69
+ validator: value => {
70
+ return arrayIncludes(['button', 'submit', 'reset'], value)
71
+ }
72
+ },
73
+ splitClass: {
74
+ type: [PROP_TYPE_ARRAY, PROP_TYPE_OBJECT, PROP_TYPE_STRING],
75
+ required: false,
76
+ default: undefined
77
+ },
78
+ splitHref: {
79
+ type: PROP_TYPE_STRING,
80
+ required: false,
81
+ default: undefined
82
+ },
83
+ splitTo: {
84
+ type: [PROP_TYPE_OBJECT, PROP_TYPE_STRING],
85
+ required: false,
86
+ default: undefined
87
+ },
88
+ splitVariant: {
89
+ type: PROP_TYPE_STRING,
90
+ required: false,
91
+ default: undefined
92
+ },
93
+ text: {
94
+ type: PROP_TYPE_STRING,
95
+ required: false,
96
+ default: undefined
97
+ },
98
+ toggleAttrs: {
99
+ type: PROP_TYPE_OBJECT,
100
+ required: false,
101
+ default: () => ({})
102
+ },
103
+ toggleClass: {
104
+ type: [PROP_TYPE_ARRAY, PROP_TYPE_OBJECT, PROP_TYPE_STRING],
105
+ required: false,
106
+ default: undefined
107
+ },
108
+ toggleTag: {
109
+ type: PROP_TYPE_STRING,
110
+ required: false,
111
+ default: 'button'
112
+ },
46
113
  // TODO: This really should be `toggleLabel`
47
- toggleText: makeProp(PROP_TYPE_STRING, 'Toggle dropdown'),
48
- variant: makeProp(PROP_TYPE_STRING, 'secondary')
114
+ toggleText: {
115
+ type: PROP_TYPE_STRING,
116
+ required: false,
117
+ default: 'Toggle dropdown'
118
+ },
119
+ variant: {
120
+ type: PROP_TYPE_STRING,
121
+ required: false,
122
+ default: 'secondary'
123
+ }
49
124
  })
50
125
 
51
126
  // --- Main component ---