@gitlab/ui 114.1.0 → 114.1.2

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 (141) hide show
  1. package/dist/components/base/breadcrumb/breadcrumb.js +4 -16
  2. package/dist/index.css +1 -1
  3. package/dist/index.css.map +1 -1
  4. package/package.json +7 -26
  5. package/src/components/base/breadcrumb/breadcrumb.scss +18 -2
  6. package/src/components/base/breadcrumb/breadcrumb.vue +4 -17
  7. package/CHANGELOG.md +0 -13139
  8. package/src/vendor/bootstrap/LICENSE +0 -11
  9. package/src/vendor/bootstrap-vue/LICENSE +0 -11
  10. package/src/vendor/bootstrap-vue/package.json +0 -144
  11. package/src/vendor/bootstrap-vue/src/components/button/MODIFICATIONS.md +0 -16
  12. package/src/vendor/bootstrap-vue/src/components/button/README.md +0 -240
  13. package/src/vendor/bootstrap-vue/src/components/button/button-close.spec.js +0 -210
  14. package/src/vendor/bootstrap-vue/src/components/button/button.spec.js +0 -349
  15. package/src/vendor/bootstrap-vue/src/components/button/package.json +0 -105
  16. package/src/vendor/bootstrap-vue/src/components/dropdown/README.md +0 -730
  17. package/src/vendor/bootstrap-vue/src/components/dropdown/dropdown-divider.spec.js +0 -58
  18. package/src/vendor/bootstrap-vue/src/components/dropdown/dropdown-form.spec.js +0 -110
  19. package/src/vendor/bootstrap-vue/src/components/dropdown/dropdown-group.spec.js +0 -94
  20. package/src/vendor/bootstrap-vue/src/components/dropdown/dropdown-header.spec.js +0 -73
  21. package/src/vendor/bootstrap-vue/src/components/dropdown/dropdown-item-button.spec.js +0 -117
  22. package/src/vendor/bootstrap-vue/src/components/dropdown/dropdown-item.spec.js +0 -147
  23. package/src/vendor/bootstrap-vue/src/components/dropdown/dropdown-text.spec.js +0 -59
  24. package/src/vendor/bootstrap-vue/src/components/dropdown/dropdown.spec.js +0 -1121
  25. package/src/vendor/bootstrap-vue/src/components/dropdown/package.json +0 -368
  26. package/src/vendor/bootstrap-vue/src/components/form/README.md +0 -365
  27. package/src/vendor/bootstrap-vue/src/components/form/form-invalid-feedback.spec.js +0 -170
  28. package/src/vendor/bootstrap-vue/src/components/form/form-text.spec.js +0 -93
  29. package/src/vendor/bootstrap-vue/src/components/form/form-valid-feedback.spec.js +0 -157
  30. package/src/vendor/bootstrap-vue/src/components/form/form.spec.js +0 -97
  31. package/src/vendor/bootstrap-vue/src/components/form/package.json +0 -112
  32. package/src/vendor/bootstrap-vue/src/components/form-checkbox/README.md +0 -691
  33. package/src/vendor/bootstrap-vue/src/components/form-checkbox/form-checkbox-group.spec.js +0 -525
  34. package/src/vendor/bootstrap-vue/src/components/form-checkbox/form-checkbox.spec.js +0 -922
  35. package/src/vendor/bootstrap-vue/src/components/form-checkbox/package.json +0 -172
  36. package/src/vendor/bootstrap-vue/src/components/form-group/README.md +0 -339
  37. package/src/vendor/bootstrap-vue/src/components/form-group/form-group.spec.js +0 -477
  38. package/src/vendor/bootstrap-vue/src/components/form-group/package.json +0 -183
  39. package/src/vendor/bootstrap-vue/src/components/form-radio/README.md +0 -437
  40. package/src/vendor/bootstrap-vue/src/components/form-radio/form-radio-group.spec.js +0 -357
  41. package/src/vendor/bootstrap-vue/src/components/form-radio/form-radio.spec.js +0 -587
  42. package/src/vendor/bootstrap-vue/src/components/form-radio/package.json +0 -162
  43. package/src/vendor/bootstrap-vue/src/components/form-select/README.md +0 -504
  44. package/src/vendor/bootstrap-vue/src/components/form-select/form-select-option-group.spec.js +0 -138
  45. package/src/vendor/bootstrap-vue/src/components/form-select/form-select-option.spec.js +0 -75
  46. package/src/vendor/bootstrap-vue/src/components/form-select/form-select.spec.js +0 -723
  47. package/src/vendor/bootstrap-vue/src/components/form-select/package.json +0 -132
  48. package/src/vendor/bootstrap-vue/src/components/form-textarea/README.md +0 -453
  49. package/src/vendor/bootstrap-vue/src/components/form-textarea/form-textarea.spec.js +0 -1000
  50. package/src/vendor/bootstrap-vue/src/components/form-textarea/package.json +0 -122
  51. package/src/vendor/bootstrap-vue/src/components/layout/README.md +0 -791
  52. package/src/vendor/bootstrap-vue/src/components/layout/col.spec.js +0 -192
  53. package/src/vendor/bootstrap-vue/src/components/layout/form-row.spec.js +0 -45
  54. package/src/vendor/bootstrap-vue/src/components/layout/package.json +0 -99
  55. package/src/vendor/bootstrap-vue/src/components/link/README.md +0 -76
  56. package/src/vendor/bootstrap-vue/src/components/link/link.spec.js +0 -434
  57. package/src/vendor/bootstrap-vue/src/components/link/package.json +0 -57
  58. package/src/vendor/bootstrap-vue/src/components/modal/MODIFICATIONS.md +0 -30
  59. package/src/vendor/bootstrap-vue/src/components/modal/README.md +0 -1067
  60. package/src/vendor/bootstrap-vue/src/components/modal/helpers/bv-modal-event.class.spec.js +0 -82
  61. package/src/vendor/bootstrap-vue/src/components/modal/modal.spec.js +0 -1418
  62. package/src/vendor/bootstrap-vue/src/components/modal/package.json +0 -544
  63. package/src/vendor/bootstrap-vue/src/components/nav/README.md +0 -362
  64. package/src/vendor/bootstrap-vue/src/components/nav/nav-item.spec.js +0 -127
  65. package/src/vendor/bootstrap-vue/src/components/nav/nav.spec.js +0 -177
  66. package/src/vendor/bootstrap-vue/src/components/nav/package.json +0 -73
  67. package/src/vendor/bootstrap-vue/src/components/popover/README.md +0 -919
  68. package/src/vendor/bootstrap-vue/src/components/popover/package.json +0 -261
  69. package/src/vendor/bootstrap-vue/src/components/popover/popover.spec.js +0 -198
  70. package/src/vendor/bootstrap-vue/src/components/table/README.md +0 -3157
  71. package/src/vendor/bootstrap-vue/src/components/table/helpers/default-sort-compare.spec.js +0 -112
  72. package/src/vendor/bootstrap-vue/src/components/table/helpers/normalize-fields.spec.js +0 -93
  73. package/src/vendor/bootstrap-vue/src/components/table/package.json +0 -1763
  74. package/src/vendor/bootstrap-vue/src/components/table/table-busy.spec.js +0 -150
  75. package/src/vendor/bootstrap-vue/src/components/table/table-caption.spec.js +0 -176
  76. package/src/vendor/bootstrap-vue/src/components/table/table-colgroup.spec.js +0 -81
  77. package/src/vendor/bootstrap-vue/src/components/table/table-filtering.spec.js +0 -409
  78. package/src/vendor/bootstrap-vue/src/components/table/table-item-formatter.spec.js +0 -56
  79. package/src/vendor/bootstrap-vue/src/components/table/table-lite.spec.js +0 -682
  80. package/src/vendor/bootstrap-vue/src/components/table/table-pagination.spec.js +0 -133
  81. package/src/vendor/bootstrap-vue/src/components/table/table-primarykey.spec.js +0 -83
  82. package/src/vendor/bootstrap-vue/src/components/table/table-provider.spec.js +0 -411
  83. package/src/vendor/bootstrap-vue/src/components/table/table-row-details.spec.js +0 -459
  84. package/src/vendor/bootstrap-vue/src/components/table/table-selectable.spec.js +0 -1182
  85. package/src/vendor/bootstrap-vue/src/components/table/table-simple.spec.js +0 -206
  86. package/src/vendor/bootstrap-vue/src/components/table/table-sorting.spec.js +0 -858
  87. package/src/vendor/bootstrap-vue/src/components/table/table-sticky-column.spec.js +0 -377
  88. package/src/vendor/bootstrap-vue/src/components/table/table-tbody-bottom-row.spec.js +0 -94
  89. package/src/vendor/bootstrap-vue/src/components/table/table-tbody-row-events.spec.js +0 -529
  90. package/src/vendor/bootstrap-vue/src/components/table/table-tbody-top-row.spec.js +0 -88
  91. package/src/vendor/bootstrap-vue/src/components/table/table-tbody-transition.spec.js +0 -83
  92. package/src/vendor/bootstrap-vue/src/components/table/table-tfoot-custom.spec.js +0 -91
  93. package/src/vendor/bootstrap-vue/src/components/table/table-tfoot-events.spec.js +0 -137
  94. package/src/vendor/bootstrap-vue/src/components/table/table-thead-events.spec.js +0 -155
  95. package/src/vendor/bootstrap-vue/src/components/table/table-thead-top.spec.js +0 -96
  96. package/src/vendor/bootstrap-vue/src/components/table/table.spec.js +0 -692
  97. package/src/vendor/bootstrap-vue/src/components/tabs/README.md +0 -433
  98. package/src/vendor/bootstrap-vue/src/components/tabs/package.json +0 -205
  99. package/src/vendor/bootstrap-vue/src/components/tabs/tab.spec.js +0 -330
  100. package/src/vendor/bootstrap-vue/src/components/tabs/tabs.spec.js +0 -778
  101. package/src/vendor/bootstrap-vue/src/components/toast/README.md +0 -655
  102. package/src/vendor/bootstrap-vue/src/components/toast/helpers/bv-toast.spec.js +0 -117
  103. package/src/vendor/bootstrap-vue/src/components/toast/package.json +0 -184
  104. package/src/vendor/bootstrap-vue/src/components/toast/toast.spec.js +0 -294
  105. package/src/vendor/bootstrap-vue/src/components/toast/toaster.spec.js +0 -77
  106. package/src/vendor/bootstrap-vue/src/components/tooltip/README.md +0 -559
  107. package/src/vendor/bootstrap-vue/src/components/tooltip/package.json +0 -258
  108. package/src/vendor/bootstrap-vue/src/components/tooltip/tooltip.spec.js +0 -1240
  109. package/src/vendor/bootstrap-vue/src/components/transition/package.json +0 -5
  110. package/src/vendor/bootstrap-vue/src/components/transporter/package.json +0 -5
  111. package/src/vendor/bootstrap-vue/src/components/transporter/transporter.spec.js +0 -85
  112. package/src/vendor/bootstrap-vue/src/directives/modal/modal.spec.js +0 -191
  113. package/src/vendor/bootstrap-vue/src/directives/tooltip/README.md +0 -521
  114. package/src/vendor/bootstrap-vue/src/directives/tooltip/package.json +0 -131
  115. package/src/vendor/bootstrap-vue/src/directives/tooltip/tooltip.spec.js +0 -190
  116. package/src/vendor/bootstrap-vue/src/directives/visible/README.md +0 -244
  117. package/src/vendor/bootstrap-vue/src/directives/visible/package.json +0 -24
  118. package/src/vendor/bootstrap-vue/src/mixins/attrs.spec.js +0 -194
  119. package/src/vendor/bootstrap-vue/src/mixins/click-out.spec.js +0 -52
  120. package/src/vendor/bootstrap-vue/src/mixins/focus-in.spec.js +0 -53
  121. package/src/vendor/bootstrap-vue/src/mixins/listen-on-document.spec.js +0 -117
  122. package/src/vendor/bootstrap-vue/src/mixins/listen-on-root.spec.js +0 -77
  123. package/src/vendor/bootstrap-vue/src/mixins/listen-on-window.spec.js +0 -115
  124. package/src/vendor/bootstrap-vue/src/mixins/listeners.spec.js +0 -245
  125. package/src/vendor/bootstrap-vue/src/utils/bv-event.class.spec.js +0 -66
  126. package/src/vendor/bootstrap-vue/src/utils/clone-deep.spec.js +0 -70
  127. package/src/vendor/bootstrap-vue/src/utils/config.spec.js +0 -169
  128. package/src/vendor/bootstrap-vue/src/utils/css-escape.spec.js +0 -82
  129. package/src/vendor/bootstrap-vue/src/utils/dom.spec.js +0 -291
  130. package/src/vendor/bootstrap-vue/src/utils/events.spec.js +0 -41
  131. package/src/vendor/bootstrap-vue/src/utils/get.spec.js +0 -109
  132. package/src/vendor/bootstrap-vue/src/utils/inspect.spec.js +0 -251
  133. package/src/vendor/bootstrap-vue/src/utils/loose-equal.spec.js +0 -203
  134. package/src/vendor/bootstrap-vue/src/utils/normalize-slot.spec.js +0 -63
  135. package/src/vendor/bootstrap-vue/src/utils/number.spec.js +0 -72
  136. package/src/vendor/bootstrap-vue/src/utils/object.spec.js +0 -61
  137. package/src/vendor/bootstrap-vue/src/utils/props.spec.js +0 -112
  138. package/src/vendor/bootstrap-vue/src/utils/router.spec.js +0 -248
  139. package/src/vendor/bootstrap-vue/src/utils/string.spec.js +0 -65
  140. package/src/vendor/bootstrap-vue/src/utils/stringify-object-values.spec.js +0 -47
  141. package/src/vendor/bootstrap-vue/src/utils/warn.spec.js +0 -54
@@ -1,778 +0,0 @@
1
- import { mount } from '@vue/test-utils'
2
- import { waitNT } from '../../../tests/utils'
3
- import { BLink } from '../link/link'
4
- import { BTab } from './tab'
5
- import { BTabs } from './tabs'
6
-
7
- describe('tabs', () => {
8
- it('default has expected classes and structure', async () => {
9
- const wrapper = mount(BTabs)
10
-
11
- await waitNT(wrapper.vm)
12
- expect(wrapper).toBeDefined()
13
-
14
- expect(wrapper.element.tagName).toBe('DIV')
15
- expect(wrapper.classes()).toContain('tabs')
16
- expect(wrapper.classes()).not.toContain('row')
17
- expect(wrapper.classes()).not.toContain('no-gutters')
18
- expect(wrapper.attributes('id')).toBeDefined()
19
-
20
- wrapper.destroy()
21
- })
22
-
23
- it('default has expected data state', async () => {
24
- const wrapper = mount(BTabs)
25
-
26
- await waitNT(wrapper.vm)
27
- expect(wrapper).toBeDefined()
28
-
29
- expect(wrapper.vm.currentTab).toBe(-1)
30
- expect(wrapper.vm.tabs.length).toBe(0)
31
-
32
- wrapper.destroy()
33
- })
34
-
35
- it('sets correct tab active for initial value', async () => {
36
- const tabIndex = 1
37
- const wrapper = mount(BTabs, {
38
- propsData: { value: tabIndex },
39
- slots: {
40
- default: {
41
- components: { BTab },
42
- template: '<div><b-tab /><b-tab /><b-tab /></div>'
43
- }
44
- }
45
- })
46
-
47
- await waitNT(wrapper.vm)
48
- expect(wrapper).toBeDefined()
49
-
50
- expect(wrapper.vm.currentTab).toBe(tabIndex)
51
- expect(wrapper.vm.tabs.length).toBe(3)
52
- expect(wrapper.vm.tabs[tabIndex].localActive).toBe(true)
53
-
54
- wrapper.destroy()
55
- })
56
-
57
- it('sets correct tab active when first tab is disabled', async () => {
58
- const App = {
59
- render(h) {
60
- return h(BTabs, [
61
- h(BTab, { props: { disabled: true } }, 'tab 0'),
62
- h(BTab, { props: {} }, 'tab 1'),
63
- h(BTab, { props: {} }, 'tab 2')
64
- ])
65
- }
66
- }
67
-
68
- const wrapper = mount(App)
69
-
70
- await waitNT(wrapper.vm)
71
- expect(wrapper).toBeDefined()
72
-
73
- const $tabs = wrapper.findComponent(BTabs)
74
- expect($tabs).toBeDefined()
75
- expect($tabs.findAllComponents(BTab).length).toBe(3)
76
-
77
- // Expect 2nd tab (index 1) to be active
78
- expect($tabs.vm.currentTab).toBe(1)
79
- expect($tabs.vm.tabs[1].localActive).toBe(true)
80
-
81
- expect($tabs.emitted('input')).toBeDefined()
82
- expect($tabs.emitted('input').length).toBe(1)
83
- // Should emit index of 1 (2nd tab)
84
- expect($tabs.emitted('input')[0][0]).toBe(1)
85
-
86
- wrapper.destroy()
87
- })
88
-
89
- it('sets current index based on active prop of b-tab', async () => {
90
- const App = {
91
- render(h) {
92
- return h(BTabs, [
93
- h(BTab, { props: { active: false } }, 'tab 0'),
94
- h(BTab, { props: { active: true } }, 'tab 1'),
95
- h(BTab, { props: { active: false } }, 'tab 2')
96
- ])
97
- }
98
- }
99
-
100
- const wrapper = mount(App)
101
-
102
- await waitNT(wrapper.vm)
103
- expect(wrapper).toBeDefined()
104
-
105
- const $tabs = wrapper.findComponent(BTabs)
106
- expect($tabs).toBeDefined()
107
- expect($tabs.findAllComponents(BTab).length).toBe(3)
108
-
109
- // Expect 2nd tab (index 1) to be active
110
- expect($tabs.vm.currentTab).toBe(1)
111
- expect($tabs.vm.tabs[1].localActive).toBe(true)
112
-
113
- expect($tabs.emitted('input')).toBeDefined()
114
- expect($tabs.emitted('input').length).toBe(1)
115
- // Should emit index of 1 (2nd tab)
116
- expect($tabs.emitted('input')[0][0]).toBe(1)
117
-
118
- wrapper.destroy()
119
- })
120
-
121
- it('selects first non-disabled tab when active tab disabled', async () => {
122
- const App = {
123
- props: {
124
- activeTab: { type: Number, default: 1 }
125
- },
126
- render(h) {
127
- const { activeTab } = this
128
-
129
- return h(BTabs, [
130
- h(BTab, { props: { active: activeTab === 0, disabled: true } }, 'Tab 1'),
131
- h(BTab, { props: { active: activeTab === 1 } }, 'Tab 2'),
132
- h(BTab, { props: { active: activeTab === 2 } }, 'Tab 3')
133
- ])
134
- }
135
- }
136
-
137
- const wrapper = mount(App)
138
-
139
- await waitNT(wrapper.vm)
140
- expect(wrapper).toBeDefined()
141
-
142
- const $tabs = wrapper.findComponent(BTabs)
143
- expect($tabs).toBeDefined()
144
- expect($tabs.findAllComponents(BTab).length).toBe(3)
145
-
146
- // Expect 2nd tab (index 1) to be active
147
- expect($tabs.vm.currentTab).toBe(1)
148
- expect($tabs.findAllComponents(BTab).at(0).vm.localActive).toBe(false)
149
- expect($tabs.findAllComponents(BTab).at(1).vm.localActive).toBe(true)
150
- expect($tabs.findAllComponents(BTab).at(2).vm.localActive).toBe(false)
151
-
152
- expect($tabs.emitted('input')).toBeDefined()
153
- expect($tabs.emitted('input').length).toBe(1)
154
- // Should emit index of 1 (2nd tab)
155
- expect($tabs.emitted('input')[0][0]).toBe(1)
156
-
157
- // Deactivate current tab (BTab 2, index 1)
158
- await wrapper.setProps({ activeTab: -1 })
159
-
160
- // Expect last tab (index 2) to be active
161
- expect($tabs.vm.currentTab).toBe(2)
162
- expect($tabs.findAllComponents(BTab).at(0).vm.localActive).toBe(false)
163
- expect($tabs.findAllComponents(BTab).at(1).vm.localActive).toBe(false)
164
- expect($tabs.findAllComponents(BTab).at(2).vm.localActive).toBe(true)
165
- expect($tabs.emitted('input').length).toBe(2)
166
- expect($tabs.emitted('input')[1][0]).toBe(2)
167
-
168
- wrapper.destroy()
169
- })
170
-
171
- it('v-model works', async () => {
172
- const App = {
173
- props: {
174
- activeTab: { type: Number, default: 0 }
175
- },
176
- render(h) {
177
- return h(BTabs, { props: { value: this.activeTab } }, [
178
- h(BTab, 'Tab 1'),
179
- h(BTab, 'Tab 2'),
180
- h(BTab, 'Tab 3')
181
- ])
182
- }
183
- }
184
-
185
- const wrapper = mount(App)
186
-
187
- await waitNT(wrapper.vm)
188
- expect(wrapper).toBeDefined()
189
-
190
- const $tabs = wrapper.findComponent(BTabs)
191
- expect($tabs).toBeDefined()
192
- expect($tabs.findAllComponents(BTab).length).toBe(3)
193
-
194
- // Expect 1st tab (index 0) to be active
195
- expect($tabs.vm.currentTab).toBe(0)
196
- expect($tabs.vm.tabs[0].localActive).toBe(true)
197
- // It should not emit an input event as the value is the same
198
- expect($tabs.emitted('input')).toBeUndefined()
199
-
200
- // Set 2nd BTab to be active
201
- await wrapper.setProps({ activeTab: 1 })
202
- expect($tabs.vm.currentTab).toBe(1)
203
- expect($tabs.emitted('input').length).toBe(1)
204
- // Should emit index of 1 (2nd tab)
205
- expect($tabs.emitted('input')[0][0]).toBe(1)
206
-
207
- // Set 3rd BTab to be active
208
- await wrapper.setProps({ activeTab: 2 })
209
- expect($tabs.vm.currentTab).toBe(2)
210
- expect($tabs.emitted('input').length).toBe(2)
211
- // Should emit index of 2 (3rd tab)
212
- expect($tabs.emitted('input')[1][0]).toBe(2)
213
-
214
- wrapper.destroy()
215
- })
216
-
217
- it('v-model works when trying to activate a disabled tab', async () => {
218
- const App = {
219
- props: {
220
- activeTab: { type: Number, default: 0 }
221
- },
222
- render(h) {
223
- return h(BTabs, { props: { value: this.activeTab } }, [
224
- h(BTab, 'Tab 1'),
225
- h(BTab, { props: { disabled: true } }, 'Tab 2'),
226
- h(BTab, 'Tab 3')
227
- ])
228
- }
229
- }
230
-
231
- const wrapper = mount(App)
232
-
233
- await waitNT(wrapper.vm)
234
- expect(wrapper).toBeDefined()
235
-
236
- const $tabs = wrapper.findComponent(BTabs)
237
- expect($tabs).toBeDefined()
238
- expect($tabs.findAllComponents(BTab).length).toBe(3)
239
-
240
- // Expect 1st tab (index 0) to be active
241
- expect($tabs.vm.currentTab).toBe(0)
242
- expect($tabs.vm.tabs[0].localActive).toBe(true)
243
- expect($tabs.emitted('input')).toBeUndefined()
244
-
245
- // Try to set 2nd (disabled) BTab to be active
246
- await wrapper.setProps({ activeTab: 1 })
247
- // Will try activate next non-disabled tab instead (3rd tab, index 2)
248
- expect($tabs.vm.currentTab).toBe(2)
249
- expect($tabs.emitted('input').length).toBe(1)
250
- // Should emit index of 2 (3rd tab)
251
- expect($tabs.emitted('input')[0][0]).toBe(2)
252
-
253
- // Needed for test since value not bound to actual v-model on App
254
- await wrapper.setProps({ activeTab: 2 })
255
- // Try and set 2nd BTab to be active
256
- await wrapper.setProps({ activeTab: 1 })
257
- // Will find the previous non-disabled tab (1st tab, index 0)
258
- expect($tabs.vm.currentTab).toBe(0)
259
- expect($tabs.emitted('input').length).toBe(2)
260
- // Should emit index of 0 (1st tab)
261
- expect($tabs.emitted('input')[1][0]).toBe(0)
262
-
263
- wrapper.destroy()
264
- })
265
-
266
- it('`activate-tab` event works', async () => {
267
- const App = {
268
- props: {
269
- activeTab: { type: Number, default: 0 }
270
- },
271
- methods: {
272
- preventTab(next, prev, bvEvent) {
273
- // Prevent 3rd tab (index === 2) from activating
274
- if (next === 2) {
275
- bvEvent.preventDefault()
276
- }
277
- }
278
- },
279
- render(h) {
280
- return h(
281
- BTabs,
282
- {
283
- props: { value: this.activeTab },
284
- on: { 'activate-tab': this.preventTab }
285
- },
286
- [h(BTab, 'Tab 1'), h(BTab, 'Tab 2'), h(BTab, 'Tab 3')]
287
- )
288
- }
289
- }
290
-
291
- const wrapper = mount(App)
292
-
293
- await waitNT(wrapper.vm)
294
- expect(wrapper).toBeDefined()
295
-
296
- const $tabs = wrapper.findComponent(BTabs)
297
- expect($tabs).toBeDefined()
298
- expect($tabs.findAllComponents(BTab).length).toBe(3)
299
-
300
- // Expect 1st tab (index 0) to be active
301
- expect($tabs.vm.currentTab).toBe(0)
302
- expect($tabs.vm.tabs[0].localActive).toBe(true)
303
- expect($tabs.emitted('input')).toBeUndefined()
304
- expect($tabs.emitted('activate-tab')).toBeUndefined()
305
-
306
- // Set 2nd BTab to be active
307
- await wrapper.setProps({ activeTab: 1 })
308
- expect($tabs.vm.currentTab).toBe(1)
309
- expect($tabs.emitted('input')).toBeDefined()
310
- expect($tabs.emitted('input').length).toBe(1)
311
- expect($tabs.emitted('input')[0][0]).toBe(1)
312
- expect($tabs.emitted('activate-tab')).toBeDefined()
313
- expect($tabs.emitted('activate-tab').length).toBe(1)
314
- expect($tabs.emitted('activate-tab')[0][0]).toBe(1)
315
- expect($tabs.emitted('activate-tab')[0][1]).toBe(0)
316
- expect($tabs.emitted('activate-tab')[0][2]).toBeDefined()
317
- expect($tabs.emitted('activate-tab')[0][2].vueTarget).toBe($tabs.vm)
318
-
319
- // Attempt to set 3rd BTab to be active
320
- await wrapper.setProps({ activeTab: 2 })
321
- expect($tabs.vm.currentTab).toBe(1)
322
- expect($tabs.emitted('input')).toBeDefined()
323
- expect($tabs.emitted('input').length).toBe(2)
324
- expect($tabs.emitted('input')[1][0]).toBe(1)
325
- expect($tabs.emitted('activate-tab').length).toBe(2)
326
- expect($tabs.emitted('activate-tab')[1][0]).toBe(2)
327
- expect($tabs.emitted('activate-tab')[1][1]).toBe(1)
328
- expect($tabs.emitted('activate-tab')[1][2]).toBeDefined()
329
- expect($tabs.emitted('activate-tab')[1][2].vueTarget).toBe($tabs.vm)
330
- expect($tabs.emitted('activate-tab')[1][2].defaultPrevented).toBe(true)
331
-
332
- wrapper.destroy()
333
- })
334
-
335
- it('clicking on tab activates the tab, and tab emits click event', async () => {
336
- const App = {
337
- render(h) {
338
- return h(BTabs, { props: { value: 0 } }, [
339
- h(BTab, { props: { title: 'one' } }, 'tab 0'),
340
- h(BTab, { props: { title: 'two' } }, 'tab 1'),
341
- h(BTab, { props: { title: 'three' } }, 'tab 2')
342
- ])
343
- }
344
- }
345
-
346
- const wrapper = mount(App)
347
-
348
- await waitNT(wrapper.vm)
349
- expect(wrapper).toBeDefined()
350
-
351
- const $tabs = wrapper.findComponent(BTabs)
352
- expect($tabs).toBeDefined()
353
- expect($tabs.findAllComponents(BTab).length).toBe(3)
354
-
355
- const tab1 = $tabs.findAllComponents(BTab).at(0)
356
- const tab2 = $tabs.findAllComponents(BTab).at(1)
357
- const tab3 = $tabs.findAllComponents(BTab).at(2)
358
-
359
- expect(wrapper.findAll('.nav-link')).toBeDefined()
360
- expect(wrapper.findAll('.nav-link').length).toBe(3)
361
-
362
- // Expect 1st tab (index 0) to be active
363
- expect($tabs.vm.currentTab).toBe(0)
364
- expect(tab1.vm.localActive).toBe(true)
365
- expect(tab2.vm.localActive).toBe(false)
366
- expect(tab3.vm.localActive).toBe(false)
367
-
368
- // Try to set 2nd BTab to be active via click
369
- expect(tab2.emitted('click')).toBeUndefined()
370
- await wrapper
371
- .findAll('.nav-link')
372
- .at(1)
373
- .trigger('click')
374
- expect($tabs.vm.currentTab).toBe(1)
375
- expect(tab1.vm.localActive).toBe(false)
376
- expect(tab2.vm.localActive).toBe(true)
377
- expect(tab3.vm.localActive).toBe(false)
378
- expect(tab2.emitted('click')).toBeDefined()
379
-
380
- // Try to set 3rd BTab to be active via click
381
- expect(tab3.emitted('click')).toBeUndefined()
382
- await wrapper
383
- .findAll('.nav-link')
384
- .at(2)
385
- .trigger('click')
386
- expect($tabs.vm.currentTab).toBe(2)
387
- expect(tab1.vm.localActive).toBe(false)
388
- expect(tab2.vm.localActive).toBe(false)
389
- expect(tab3.vm.localActive).toBe(true)
390
- expect(tab3.emitted('click')).toBeDefined()
391
-
392
- // Try to set 1st BTab to be active via click (space === click in keynav mode)
393
- expect(tab1.emitted('click')).toBeUndefined()
394
- await wrapper
395
- .findAll('.nav-link')
396
- .at(0)
397
- .trigger('keydown.space')
398
- expect($tabs.vm.currentTab).toBe(0)
399
- expect(tab1.vm.localActive).toBe(true)
400
- expect(tab2.vm.localActive).toBe(false)
401
- expect(tab3.vm.localActive).toBe(false)
402
- expect(tab1.emitted('click')).toBeDefined()
403
-
404
- wrapper.destroy()
405
- })
406
-
407
- it('pressing space on tab activates the tab, and tab emits click event', async () => {
408
- const App = {
409
- render(h) {
410
- return h(BTabs, { props: { value: 0, noKeyNav: true } }, [
411
- h(BTab, { props: { title: 'one' } }, 'tab 0'),
412
- h(BTab, { props: { title: 'two' } }, 'tab 1'),
413
- h(BTab, { props: { title: 'three' } }, 'tab 2')
414
- ])
415
- }
416
- }
417
-
418
- const wrapper = mount(App)
419
-
420
- await waitNT(wrapper.vm)
421
- expect(wrapper).toBeDefined()
422
-
423
- const $tabs = wrapper.findComponent(BTabs)
424
- expect($tabs).toBeDefined()
425
- expect($tabs.findAllComponents(BTab).length).toBe(3)
426
-
427
- const tab1 = $tabs.findAllComponents(BTab).at(0)
428
- const tab2 = $tabs.findAllComponents(BTab).at(1)
429
- const tab3 = $tabs.findAllComponents(BTab).at(2)
430
-
431
- expect(wrapper.findAll('.nav-link')).toBeDefined()
432
- expect(wrapper.findAll('.nav-link').length).toBe(3)
433
-
434
- // Expect 1st tab (index 0) to be active
435
- expect($tabs.vm.currentTab).toBe(0)
436
- expect(tab1.vm.localActive).toBe(true)
437
- expect(tab2.vm.localActive).toBe(false)
438
- expect(tab3.vm.localActive).toBe(false)
439
-
440
- // Try to set 2nd BTab to be active via space keypress
441
- expect(tab2.emitted('click')).toBeUndefined()
442
- await wrapper
443
- .findAll('.nav-link')
444
- .at(1)
445
- .trigger('keydown.space')
446
- expect($tabs.vm.currentTab).toBe(1)
447
- expect(tab1.vm.localActive).toBe(false)
448
- expect(tab2.vm.localActive).toBe(true)
449
- expect(tab3.vm.localActive).toBe(false)
450
- expect(tab2.emitted('click')).toBeDefined()
451
-
452
- // Try to set 3rd BTab to be active via space keypress
453
- expect(tab3.emitted('click')).toBeUndefined()
454
- await wrapper
455
- .findAll('.nav-link')
456
- .at(2)
457
- .trigger('keydown.space')
458
- expect($tabs.vm.currentTab).toBe(2)
459
- expect(tab1.vm.localActive).toBe(false)
460
- expect(tab2.vm.localActive).toBe(false)
461
- expect(tab3.vm.localActive).toBe(true)
462
- expect(tab3.emitted('click')).toBeDefined()
463
-
464
- // Try to set 1st BTab to be active via space keypress
465
- expect(tab1.emitted('click')).toBeUndefined()
466
- await wrapper
467
- .findAll('.nav-link')
468
- .at(0)
469
- .trigger('keydown.space')
470
- expect($tabs.vm.currentTab).toBe(0)
471
- expect(tab1.vm.localActive).toBe(true)
472
- expect(tab2.vm.localActive).toBe(false)
473
- expect(tab3.vm.localActive).toBe(false)
474
- expect(tab1.emitted('click')).toBeDefined()
475
-
476
- wrapper.destroy()
477
- })
478
-
479
- it('key nav works', async () => {
480
- const App = {
481
- render(h) {
482
- return h(BTabs, { props: { value: 0 } }, [
483
- h(BTab, { props: { title: 'one' } }, 'tab 0'),
484
- h(BTab, { props: { title: 'two' } }, 'tab 1'),
485
- h(BTab, { props: { title: 'three' } }, 'tab 2')
486
- ])
487
- }
488
- }
489
-
490
- const wrapper = mount(App)
491
-
492
- await waitNT(wrapper.vm)
493
- expect(wrapper).toBeDefined()
494
-
495
- const $tabs = wrapper.findComponent(BTabs)
496
- expect($tabs).toBeDefined()
497
- expect($tabs.findAllComponents(BTab).length).toBe(3)
498
-
499
- const tab1 = $tabs.findAllComponents(BTab).at(0)
500
- const tab2 = $tabs.findAllComponents(BTab).at(1)
501
- const tab3 = $tabs.findAllComponents(BTab).at(2)
502
-
503
- expect(wrapper.findAll('.nav-link')).toBeDefined()
504
- expect(wrapper.findAll('.nav-link').length).toBe(3)
505
-
506
- // Expect 1st tab (index 0) to be active
507
- expect($tabs.vm.currentTab).toBe(0)
508
- expect(tab1.vm.localActive).toBe(true)
509
- expect(tab2.vm.localActive).toBe(false)
510
- expect(tab3.vm.localActive).toBe(false)
511
-
512
- // RIGHT moves to next tab
513
- await wrapper
514
- .findAllComponents(BLink)
515
- .at(0)
516
- .trigger('keydown.right')
517
- expect($tabs.vm.currentTab).toBe(1)
518
- expect(tab1.vm.localActive).toBe(false)
519
- expect(tab2.vm.localActive).toBe(true)
520
- expect(tab3.vm.localActive).toBe(false)
521
-
522
- // END key moves to last tab
523
- await wrapper
524
- .findAllComponents(BLink)
525
- .at(1)
526
- .trigger('keydown.end')
527
- expect($tabs.vm.currentTab).toBe(2)
528
- expect(tab1.vm.localActive).toBe(false)
529
- expect(tab2.vm.localActive).toBe(false)
530
- expect(tab3.vm.localActive).toBe(true)
531
-
532
- // LEFT moves to previous tab
533
- await wrapper
534
- .findAllComponents(BLink)
535
- .at(2)
536
- .trigger('keydown.left')
537
- expect($tabs.vm.currentTab).toBe(1)
538
- expect(tab1.vm.localActive).toBe(false)
539
- expect(tab2.vm.localActive).toBe(true)
540
- expect(tab3.vm.localActive).toBe(false)
541
-
542
- // HOME moves to first tab
543
- await wrapper
544
- .findAllComponents(BLink)
545
- .at(1)
546
- .trigger('keydown.home')
547
- expect($tabs.vm.currentTab).toBe(0)
548
- expect(tab1.vm.localActive).toBe(true)
549
- expect(tab2.vm.localActive).toBe(false)
550
- expect(tab3.vm.localActive).toBe(false)
551
-
552
- wrapper.destroy()
553
- })
554
-
555
- it('disabling active tab selects first non-disabled tab', async () => {
556
- const App = {
557
- props: {
558
- disabledTabs: { type: Array, default: () => [] }
559
- },
560
- render(h) {
561
- const { disabledTabs } = this
562
-
563
- return h(BTabs, { props: { value: 2 } }, [
564
- h(BTab, { props: { disabled: disabledTabs.indexOf(0) !== -1 } }, 'Tab 1'),
565
- h(BTab, { props: { disabled: disabledTabs.indexOf(1) !== -1 } }, 'Tab 2'),
566
- h(BTab, { props: { disabled: disabledTabs.indexOf(2) !== -1 } }, 'Tab 3')
567
- ])
568
- }
569
- }
570
-
571
- const wrapper = mount(App)
572
-
573
- await waitNT(wrapper.vm)
574
- expect(wrapper).toBeDefined()
575
-
576
- const $tabs = wrapper.findComponent(BTabs)
577
- expect($tabs).toBeDefined()
578
- expect($tabs.findAllComponents(BTab).length).toBe(3)
579
-
580
- const tab1 = $tabs.findAllComponents(BTab).at(0)
581
- const tab2 = $tabs.findAllComponents(BTab).at(1)
582
- const tab3 = $tabs.findAllComponents(BTab).at(2)
583
-
584
- // Expect 3rd tab (index 2) to be active
585
- expect($tabs.vm.currentTab).toBe(2)
586
- expect(tab1.vm.localActive).toBe(false)
587
- expect(tab2.vm.localActive).toBe(false)
588
- expect(tab3.vm.localActive).toBe(true)
589
-
590
- // Disable 3rd tab
591
- await wrapper.setProps({ disabledTabs: [2] })
592
-
593
- // Expect 1st tab to be active
594
- expect($tabs.vm.currentTab).toBe(0)
595
- expect(tab1.vm.localActive).toBe(true)
596
- expect(tab2.vm.localActive).toBe(false)
597
- expect(tab3.vm.localActive).toBe(false)
598
-
599
- // Enable 3rd tab and Disable 1st tab
600
- await wrapper.setProps({ disabledTabs: [0] })
601
-
602
- // Expect 2nd tab to be active
603
- expect($tabs.vm.currentTab).toBe(1)
604
- expect(tab1.vm.localActive).toBe(false)
605
- expect(tab2.vm.localActive).toBe(true)
606
- expect(tab3.vm.localActive).toBe(false)
607
-
608
- wrapper.destroy()
609
- })
610
-
611
- it('tab title slots are reactive', async () => {
612
- const App = {
613
- render(h) {
614
- return h(BTabs, { props: { value: 2 } }, [
615
- h(BTab, { props: { title: 'original' } }, 'tab content')
616
- ])
617
- }
618
- }
619
-
620
- const wrapper = mount(App)
621
-
622
- await waitNT(wrapper.vm)
623
- expect(wrapper).toBeDefined()
624
-
625
- const $tabs = wrapper.findComponent(BTabs)
626
- expect($tabs).toBeDefined()
627
- expect($tabs.findAllComponents(BTab).length).toBe(1)
628
-
629
- // Expect tab button content to be `original`
630
- expect(wrapper.find('.nav-link').text()).toBe('original')
631
-
632
- // Get the BTab's instance
633
- const tabVm = wrapper.findComponent(BTab).vm
634
- expect(tabVm).toBeDefined()
635
-
636
- // Change title slot content
637
- tabVm.$slots.title = [tabVm.$createElement('span', 'foobar')]
638
- tabVm.$forceUpdate()
639
- await waitNT(wrapper.vm)
640
-
641
- // Expect tab button content to be `foobar`
642
- expect(wrapper.find('.nav-link').text()).toBe('foobar')
643
-
644
- wrapper.destroy()
645
- })
646
-
647
- it('"active-nav-item-class" is applied to active nav item', async () => {
648
- const activeNavItemClass = 'text-success'
649
- const App = {
650
- props: {
651
- activeTab: { type: Number, default: 0 }
652
- },
653
- render(h) {
654
- return h(BTabs, { props: { value: this.activeTab, activeNavItemClass } }, [
655
- h(BTab, 'Tab 1'),
656
- h(BTab, 'Tab 2'),
657
- h(BTab, 'Tab 3')
658
- ])
659
- }
660
- }
661
-
662
- const wrapper = mount(App)
663
-
664
- await waitNT(wrapper.vm)
665
- expect(wrapper).toBeDefined()
666
-
667
- const $tabs = wrapper.findComponent(BTabs)
668
- expect($tabs).toBeDefined()
669
- expect($tabs.findAllComponents(BTab).length).toBe(3)
670
-
671
- const getNavItemByTab = tab => wrapper.find(`#${tab.$el.id}___BV_tab_button__`)
672
-
673
- // Expect 1st tab (index 0) to be active
674
- expect($tabs.vm.currentTab).toBe(0)
675
- expect($tabs.vm.tabs[0].localActive).toBe(true)
676
- // Expect 1st tabs nav item to have "active-nav-item-class" applied
677
- expect(getNavItemByTab($tabs.vm.tabs[0]).classes(activeNavItemClass)).toBe(true)
678
-
679
- // Set 2nd tab to be active
680
- wrapper.setProps({ activeTab: 1 })
681
- await waitNT(wrapper.vm)
682
- expect($tabs.vm.currentTab).toBe(1)
683
- // Expect 2nd tabs nav item to have "active-nav-item-class" applied
684
- expect(getNavItemByTab($tabs.vm.tabs[1]).classes(activeNavItemClass)).toBe(true)
685
- // Expect 1st tabs nav item to don't have "active-nav-item-class" applied anymore
686
- expect(getNavItemByTab($tabs.vm.tabs[0]).classes(activeNavItemClass)).toBe(false)
687
-
688
- wrapper.destroy()
689
- })
690
-
691
- it('"active-tab-class" is applied to active tab', async () => {
692
- const activeTabClass = 'text-success'
693
- const App = {
694
- props: {
695
- activeTab: { type: Number, default: 0 }
696
- },
697
- render(h) {
698
- return h(BTabs, { props: { value: this.activeTab, activeTabClass } }, [
699
- h(BTab, 'Tab 1'),
700
- h(BTab, 'Tab 2'),
701
- h(BTab, 'Tab 3')
702
- ])
703
- }
704
- }
705
-
706
- const wrapper = mount(App)
707
-
708
- await waitNT(wrapper.vm)
709
- expect(wrapper).toBeDefined()
710
-
711
- const $tabs = wrapper.findComponent(BTabs)
712
- expect($tabs).toBeDefined()
713
- expect($tabs.findAllComponents(BTab).length).toBe(3)
714
-
715
- // Expect 1st tab (index 0) to be active
716
- expect($tabs.vm.currentTab).toBe(0)
717
- expect($tabs.vm.tabs[0].localActive).toBe(true)
718
- // Expect 1st tab to have "active-tab-class" applied
719
- expect($tabs.vm.tabs[0].$el.classList.contains(activeTabClass)).toBe(true)
720
-
721
- // Set 2nd tab to be active
722
- await wrapper.setProps({ activeTab: 1 })
723
- expect($tabs.vm.currentTab).toBe(1)
724
- // Expect 2nd tab to have "active-tab-class" applied
725
- expect($tabs.vm.tabs[1].$el.classList.contains(activeTabClass)).toBe(true)
726
- // Expect 1st tab to don't have "active-tab-class" applied anymore
727
- expect($tabs.vm.tabs[0].$el.classList.contains(activeTabClass)).toBe(false)
728
-
729
- wrapper.destroy()
730
- })
731
-
732
- it('emits "changed" event when tabs change', async () => {
733
- const App = {
734
- props: {
735
- tabs: {
736
- type: Array,
737
- default: () => ['Tab 1', 'Tab 2', 'Tab 3']
738
- }
739
- },
740
- render(h) {
741
- return h(BTabs, this.tabs.map(tab => h(BTab, tab)))
742
- }
743
- }
744
-
745
- const wrapper = mount(App)
746
-
747
- await waitNT(wrapper.vm)
748
- expect(wrapper).toBeDefined()
749
-
750
- const $tabs = wrapper.findComponent(BTabs)
751
- expect($tabs).toBeDefined()
752
- expect($tabs.findAllComponents(BTab).length).toBe(3)
753
- expect($tabs.emitted('changed')).toBeDefined()
754
- expect($tabs.emitted('changed').length).toBe(1)
755
- expect($tabs.emitted('changed')[0][0].length).toBe(3)
756
- expect($tabs.emitted('changed')[0][1].length).toBe(0)
757
-
758
- // Add a tab
759
- await wrapper.setProps({ tabs: ['Tab 1', 'Tab 2', 'Tab 3', 'Tab 4'] })
760
- await waitNT(wrapper.vm)
761
- expect($tabs.findAllComponents(BTab).length).toBe(4)
762
- expect($tabs.emitted('changed')).toBeDefined()
763
- expect($tabs.emitted('changed').length).toBe(2)
764
- expect($tabs.emitted('changed')[1][0].length).toBe(4)
765
- expect($tabs.emitted('changed')[1][1].length).toBe(3)
766
-
767
- // Remove a tabs
768
- await wrapper.setProps({ tabs: ['Tab 1', 'Tab 2'] })
769
- await waitNT(wrapper.vm)
770
- expect($tabs.findAllComponents(BTab).length).toBe(2)
771
- expect($tabs.emitted('changed')).toBeDefined()
772
- expect($tabs.emitted('changed').length).toBe(3)
773
- expect($tabs.emitted('changed')[2][0].length).toBe(2)
774
- expect($tabs.emitted('changed')[2][1].length).toBe(4)
775
-
776
- wrapper.destroy()
777
- })
778
- })