quasar 2.4.13 → 2.5.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 (163) hide show
  1. package/dist/api/QCheckbox.json +27 -0
  2. package/dist/api/QRadio.json +18 -0
  3. package/dist/api/QTime.json +8 -2
  4. package/dist/api/QToggle.json +24 -24
  5. package/dist/icon-set/bootstrap-icons.umd.prod.js +1 -1
  6. package/dist/icon-set/eva-icons.umd.prod.js +1 -1
  7. package/dist/icon-set/fontawesome-v5-pro.umd.prod.js +1 -1
  8. package/dist/icon-set/fontawesome-v5.umd.prod.js +1 -1
  9. package/dist/icon-set/ionicons-v4.umd.prod.js +1 -1
  10. package/dist/icon-set/line-awesome.umd.prod.js +1 -1
  11. package/dist/icon-set/material-icons-outlined.umd.prod.js +1 -1
  12. package/dist/icon-set/material-icons-round.umd.prod.js +1 -1
  13. package/dist/icon-set/material-icons-sharp.umd.prod.js +1 -1
  14. package/dist/icon-set/material-icons.umd.prod.js +1 -1
  15. package/dist/icon-set/mdi-v3.umd.prod.js +1 -1
  16. package/dist/icon-set/mdi-v4.umd.prod.js +1 -1
  17. package/dist/icon-set/mdi-v5.umd.prod.js +1 -1
  18. package/dist/icon-set/mdi-v6.umd.prod.js +1 -1
  19. package/dist/icon-set/svg-bootstrap-icons.umd.prod.js +1 -1
  20. package/dist/icon-set/svg-eva-icons.umd.prod.js +1 -1
  21. package/dist/icon-set/svg-fontawesome-v5.umd.prod.js +1 -1
  22. package/dist/icon-set/svg-ionicons-v4.umd.prod.js +1 -1
  23. package/dist/icon-set/svg-ionicons-v5.umd.prod.js +1 -1
  24. package/dist/icon-set/svg-ionicons-v6.umd.prod.js +1 -1
  25. package/dist/icon-set/svg-line-awesome.umd.prod.js +1 -1
  26. package/dist/icon-set/svg-material-icons-outlined.umd.prod.js +1 -1
  27. package/dist/icon-set/svg-material-icons-round.umd.prod.js +1 -1
  28. package/dist/icon-set/svg-material-icons-sharp.umd.prod.js +1 -1
  29. package/dist/icon-set/svg-material-icons.umd.prod.js +1 -1
  30. package/dist/icon-set/svg-mdi-v4.umd.prod.js +1 -1
  31. package/dist/icon-set/svg-mdi-v5.umd.prod.js +1 -1
  32. package/dist/icon-set/svg-mdi-v6.umd.prod.js +1 -1
  33. package/dist/icon-set/svg-themify.umd.prod.js +1 -1
  34. package/dist/icon-set/themify.umd.prod.js +1 -1
  35. package/dist/lang/ar.umd.prod.js +1 -1
  36. package/dist/lang/az-Latn.umd.prod.js +1 -1
  37. package/dist/lang/bg.umd.prod.js +1 -1
  38. package/dist/lang/bn.umd.prod.js +1 -1
  39. package/dist/lang/ca.umd.prod.js +1 -1
  40. package/dist/lang/cs.umd.prod.js +1 -1
  41. package/dist/lang/da.umd.prod.js +1 -1
  42. package/dist/lang/de.umd.prod.js +1 -1
  43. package/dist/lang/el.umd.prod.js +1 -1
  44. package/dist/lang/en-GB.umd.prod.js +1 -1
  45. package/dist/lang/en-US.umd.prod.js +1 -1
  46. package/dist/lang/eo.umd.prod.js +1 -1
  47. package/dist/lang/es.umd.prod.js +1 -1
  48. package/dist/lang/et.umd.prod.js +1 -1
  49. package/dist/lang/fa-IR.umd.prod.js +1 -1
  50. package/dist/lang/fa.umd.prod.js +1 -1
  51. package/dist/lang/fi.umd.prod.js +1 -1
  52. package/dist/lang/fr.umd.prod.js +1 -1
  53. package/dist/lang/gn.umd.prod.js +1 -1
  54. package/dist/lang/he.umd.prod.js +1 -1
  55. package/dist/lang/hr.umd.prod.js +1 -1
  56. package/dist/lang/hu.umd.prod.js +1 -1
  57. package/dist/lang/id.umd.prod.js +1 -1
  58. package/dist/lang/is.umd.prod.js +1 -1
  59. package/dist/lang/it.umd.prod.js +1 -1
  60. package/dist/lang/ja.umd.prod.js +1 -1
  61. package/dist/lang/km.umd.prod.js +1 -1
  62. package/dist/lang/ko-KR.umd.prod.js +1 -1
  63. package/dist/lang/kur-CKB.umd.prod.js +1 -1
  64. package/dist/lang/lt.umd.prod.js +1 -1
  65. package/dist/lang/lu.umd.prod.js +1 -1
  66. package/dist/lang/lv.umd.prod.js +1 -1
  67. package/dist/lang/ml.umd.prod.js +1 -1
  68. package/dist/lang/ms.umd.prod.js +1 -1
  69. package/dist/lang/my.umd.prod.js +1 -1
  70. package/dist/lang/nb-NO.umd.prod.js +1 -1
  71. package/dist/lang/nl.umd.prod.js +1 -1
  72. package/dist/lang/pl.umd.prod.js +1 -1
  73. package/dist/lang/pt-BR.umd.prod.js +1 -1
  74. package/dist/lang/pt.umd.prod.js +1 -1
  75. package/dist/lang/ro.umd.prod.js +1 -1
  76. package/dist/lang/ru.umd.prod.js +1 -1
  77. package/dist/lang/sk.umd.prod.js +1 -1
  78. package/dist/lang/sl.umd.prod.js +1 -1
  79. package/dist/lang/sr-CYR.umd.prod.js +1 -1
  80. package/dist/lang/sr.umd.prod.js +1 -1
  81. package/dist/lang/sv.umd.prod.js +1 -1
  82. package/dist/lang/ta.umd.prod.js +1 -1
  83. package/dist/lang/th.umd.prod.js +1 -1
  84. package/dist/lang/tr.umd.prod.js +1 -1
  85. package/dist/lang/ug.umd.prod.js +1 -1
  86. package/dist/lang/uk.umd.prod.js +1 -1
  87. package/dist/lang/vi.umd.prod.js +1 -1
  88. package/dist/lang/zh-CN.umd.prod.js +1 -1
  89. package/dist/lang/zh-TW.umd.prod.js +1 -1
  90. package/dist/quasar.cjs.prod.js +2 -2
  91. package/dist/quasar.css +34 -10
  92. package/dist/quasar.esm.prod.js +2 -2
  93. package/dist/quasar.prod.css +1 -1
  94. package/dist/quasar.rtl.css +51 -23
  95. package/dist/quasar.rtl.prod.css +1 -1
  96. package/dist/quasar.sass +29 -11
  97. package/dist/quasar.umd.js +119 -49
  98. package/dist/quasar.umd.prod.js +2 -2
  99. package/dist/ssr-directives/Morph.js +1 -1
  100. package/dist/transforms/auto-import.json +39 -3
  101. package/dist/transforms/import-map.json +18 -0
  102. package/dist/types/index.d.ts +35 -13
  103. package/dist/vetur/quasar-attributes.json +32 -12
  104. package/dist/vetur/quasar-tags.json +8 -3
  105. package/dist/web-types/web-types.json +73 -28
  106. package/package.json +13 -3
  107. package/src/components/avatar/__tests__/QAvatar.spec.js +121 -0
  108. package/src/components/badge/__tests__/QBadge.spec.js +74 -0
  109. package/src/components/breadcrumbs/QBreadcrumbs.js +1 -1
  110. package/src/components/btn/__tests__/QBtn.spec.js +55 -0
  111. package/src/components/btn/__tests__/use-btn.spec.js +189 -0
  112. package/src/components/checkbox/QCheckbox.js +34 -3
  113. package/src/components/checkbox/QCheckbox.json +17 -0
  114. package/src/components/checkbox/QCheckbox.sass +17 -5
  115. package/src/components/checkbox/use-checkbox.js +4 -0
  116. package/src/components/checkbox/use-checkbox.json +18 -0
  117. package/src/components/chip/__tests__/QChip.spec.js +155 -0
  118. package/src/components/date/__tests__/QDate.spec.js +189 -0
  119. package/src/components/date/__tests__/use-datetime.spec.js +83 -0
  120. package/src/components/dialog/__tests__/QDialog.spec.js +129 -0
  121. package/src/components/editor/__tests__/QEditor.spec.js +195 -0
  122. package/src/components/input/QInput.js +9 -0
  123. package/src/components/input/__tests__/QInput.spec.js +105 -0
  124. package/src/components/input/__tests__/use-mask.spec.js +29 -0
  125. package/src/components/menu/__tests__/QMenu.spec.js +610 -0
  126. package/src/components/menu/__tests__/WrapperOne.vue +51 -0
  127. package/src/components/menu/__tests__/WrapperTwo.vue +38 -0
  128. package/src/components/radio/QRadio.js +26 -1
  129. package/src/components/radio/QRadio.json +16 -0
  130. package/src/components/radio/QRadio.sass +17 -6
  131. package/src/components/select/QSelect.js +1 -1
  132. package/src/components/select/__tests__/QSelect.spec.js +2003 -0
  133. package/src/components/select/__tests__/WrapperOne.vue +28 -0
  134. package/src/components/table/__tests__/QTable.spec.js +635 -0
  135. package/src/components/table/__tests__/QTd.spec.js +35 -0
  136. package/src/components/table/__tests__/QTh.spec.js +27 -0
  137. package/src/components/table/__tests__/QTr.spec.js +27 -0
  138. package/src/components/tabs/__tests__/QRouteTab.spec.js +9 -0
  139. package/src/components/tabs/__tests__/QTab.spec.js +79 -0
  140. package/src/components/tabs/__tests__/QTabs.spec.js +147 -0
  141. package/src/components/time/QTime.json +2 -2
  142. package/src/components/toggle/QToggle.js +5 -13
  143. package/src/components/toggle/QToggle.json +3 -12
  144. package/src/components/uploader/__tests__/QUploader.spec.js +161 -0
  145. package/src/composables/private/__tests__/FieldWrapper.vue +39 -0
  146. package/src/composables/private/__tests__/use-anchor.spec.js +99 -0
  147. package/src/composables/private/__tests__/use-field.spec.js +351 -0
  148. package/src/composables/private/__tests__/use-file.spec.js +69 -0
  149. package/src/composables/private/__tests__/use-form.spec.js +11 -0
  150. package/src/composables/private/__tests__/use-fullscreen.spec.js +37 -0
  151. package/src/composables/private/__tests__/use-model-toggle.spec.js +306 -0
  152. package/src/composables/private/__tests__/use-portal.spec.js +4 -0
  153. package/src/composables/private/__tests__/use-router-link.spec.js +55 -0
  154. package/src/composables/private/__tests__/use-size.spec.js +37 -0
  155. package/src/composables/private/__tests__/use-transition.spec.js +108 -0
  156. package/src/composables/private/__tests__/use-validate.spec.js +111 -0
  157. package/src/composables/private/use-fullscreen.js +1 -1
  158. package/src/composables/private/use-model-toggle.js +1 -1
  159. package/src/composables/private/use-validate.js +9 -5
  160. package/src/plugins/Meta.js +1 -1
  161. package/src/plugins/Screen.js +11 -8
  162. package/src/utils/date.js +5 -5
  163. package/src/utils/private/vm.js +14 -8
@@ -0,0 +1,306 @@
1
+ /* eslint-disable no-unused-expressions */
2
+ import { mount } from '@cypress/vue'
3
+ import WrapperOne from './../../../components/menu/__tests__/WrapperOne.vue'
4
+ import WrapperTwo from './../../../components/menu/__tests__/WrapperTwo.vue'
5
+ import { ref } from 'vue'
6
+
7
+ describe('use-model-toggle API', () => {
8
+ describe('Props', () => {
9
+ describe('Category: model', () => {
10
+ describe('(prop): model-value', () => {
11
+ it('should open the dialog when modifying the model-value', () => {
12
+ const modelValue = ref(false)
13
+ mount(WrapperOne, {
14
+ attrs: {
15
+ modelValue
16
+ }
17
+ })
18
+ cy.dataCy('wrapper')
19
+ cy.dataCy('menu')
20
+ .should('not.exist')
21
+ .then(() => {
22
+ modelValue.value = true
23
+ cy.dataCy('menu')
24
+ .should('exist')
25
+ })
26
+ })
27
+
28
+ it('should close the dialog when modifying the model-value', () => {
29
+ const modelValue = ref(true)
30
+ mount(WrapperOne, {
31
+ attrs: {
32
+ modelValue
33
+ }
34
+ })
35
+ cy.dataCy('wrapper')
36
+ cy.dataCy('menu')
37
+ .should('exist')
38
+ .then(() => {
39
+ modelValue.value = false
40
+ cy.dataCy('menu')
41
+ .should('not.exist')
42
+ })
43
+ })
44
+ })
45
+ })
46
+ })
47
+
48
+ describe('Events', () => {
49
+ describe('(event): update:model-value', () => {
50
+ it('should emit @update:model-value event when state changes', () => {
51
+ const fn = cy.stub()
52
+ mount(WrapperOne, {
53
+ attrs: {
54
+ 'onUpdate:modelValue': fn
55
+ }
56
+ })
57
+
58
+ expect(fn).not.to.be.called
59
+ cy.dataCy('wrapper')
60
+ .click()
61
+ cy.dataCy('menu')
62
+ .should('exist')
63
+ .then(() => {
64
+ expect(fn).to.be.called
65
+ })
66
+ })
67
+ })
68
+
69
+ describe('(event): show', () => {
70
+ it('should emit @show event when menu is triggered by parent', () => {
71
+ const fn = cy.stub()
72
+ mount(WrapperOne, {
73
+ attrs: {
74
+ onShow: fn
75
+ }
76
+ })
77
+
78
+ expect(fn).not.to.be.called
79
+ cy.dataCy('wrapper')
80
+ .click()
81
+ cy.dataCy('menu')
82
+ .should('exist')
83
+ .wait(300) // Await menu animation
84
+ .then(() => {
85
+ expect(fn).to.be.called
86
+ })
87
+ })
88
+
89
+ it('should emit @show event when component is triggered with the show() method', () => {
90
+ const fn = cy.stub()
91
+ mount(WrapperOne, {
92
+ attrs: {
93
+ onShow: fn
94
+ }
95
+ })
96
+
97
+ expect(fn).not.to.be.called
98
+ cy.dataCy('wrapper')
99
+ cy.dataCy('method-show')
100
+ .click({ force: true }) // Element is hidden to prevent clogging the window
101
+ cy.dataCy('menu')
102
+ .should('exist')
103
+ .wait(300) // Await menu animation
104
+ .then(() => {
105
+ expect(fn).to.be.called
106
+ })
107
+ })
108
+ })
109
+
110
+ describe('(event): before-show', () => {
111
+ it('should emit @before-show event when menu is triggered by parent', () => {
112
+ const fn = cy.stub()
113
+ mount(WrapperOne, {
114
+ attrs: {
115
+ onBeforeShow: fn
116
+ }
117
+ })
118
+
119
+ expect(fn).not.to.be.called
120
+ cy.dataCy('wrapper')
121
+ .click()
122
+ cy.dataCy('menu')
123
+ .should('exist')
124
+ .then(() => {
125
+ expect(fn).to.be.called
126
+ })
127
+ })
128
+
129
+ it('should emit @before-show event when component is triggered with the show() method', () => {
130
+ const fn = cy.stub()
131
+ mount(WrapperOne, {
132
+ attrs: {
133
+ onBeforeShow: fn
134
+ }
135
+ })
136
+
137
+ expect(fn).not.to.be.called
138
+ cy.dataCy('wrapper')
139
+ cy.dataCy('method-show')
140
+ .click({ force: true }) // Element is hidden to prevent clogging the window
141
+ cy.dataCy('menu')
142
+ .should('exist')
143
+ .then(() => {
144
+ expect(fn).to.be.called
145
+ })
146
+ })
147
+ })
148
+
149
+ describe('(event): hide', () => {
150
+ it('should emit @hide event when menu is triggered by parent', () => {
151
+ const fn = cy.stub()
152
+ mount(WrapperOne, {
153
+ attrs: {
154
+ onHide: fn
155
+ }
156
+ })
157
+
158
+ expect(fn).not.to.be.called
159
+ cy.dataCy('wrapper')
160
+ .click()
161
+ cy.dataCy('menu')
162
+ .should('exist')
163
+ .then(() => {
164
+ expect(fn).not.to.be.called
165
+ })
166
+ cy.get('body')
167
+ .click(499, 0)
168
+ cy.dataCy('menu')
169
+ .should('not.exist')
170
+ .then(() => {
171
+ expect(fn).to.be.called
172
+ })
173
+ })
174
+
175
+ it('should emit @hide event when component is triggered with the show() method', () => {
176
+ const fn = cy.stub()
177
+ mount(WrapperOne, {
178
+ attrs: {
179
+ onHide: fn
180
+ }
181
+ })
182
+
183
+ expect(fn).not.to.be.called
184
+ cy.dataCy('wrapper')
185
+ cy.dataCy('method-show')
186
+ .click({ force: true }) // Element is hidden to prevent clogging the window
187
+ cy.dataCy('menu')
188
+ .should('exist')
189
+ .then(() => {
190
+ expect(fn).not.to.be.called
191
+ })
192
+ cy.dataCy('method-hide')
193
+ .click({ force: true })
194
+ cy.dataCy('menu')
195
+ .should('not.exist') // Element is hidden to prevent clogging the window
196
+ .then(() => {
197
+ expect(fn).to.be.called
198
+ })
199
+ })
200
+ })
201
+
202
+ describe('(event): before-hide', () => {
203
+ it('should emit @before-hide event when menu is triggered by parent', () => {
204
+ const fn = cy.stub()
205
+ mount(WrapperOne, {
206
+ attrs: {
207
+ onBeforeHide: fn
208
+ }
209
+ })
210
+
211
+ expect(fn).not.to.be.called
212
+ cy.dataCy('wrapper')
213
+ .click()
214
+ cy.dataCy('menu')
215
+ .should('exist')
216
+ .then(() => {
217
+ expect(fn).not.to.be.called
218
+ })
219
+ cy.get('body')
220
+ .click(499, 0)
221
+ .then(() => {
222
+ expect(fn).to.be.called
223
+ })
224
+ cy.dataCy('menu')
225
+ .should('not.exist')
226
+ })
227
+
228
+ it('should emit @before-hide event when component is triggered with the show() method', () => {
229
+ const fn = cy.stub()
230
+ mount(WrapperOne, {
231
+ attrs: {
232
+ onBeforeHide: fn
233
+ }
234
+ })
235
+
236
+ expect(fn).not.to.be.called
237
+ cy.dataCy('wrapper')
238
+ cy.dataCy('method-show')
239
+ .click({ force: true }) // Element is hidden to prevent clogging the window
240
+ cy.dataCy('menu')
241
+ .should('exist')
242
+ .then(() => {
243
+ expect(fn).not.to.be.called
244
+ })
245
+ cy.dataCy('method-hide')
246
+ .click({ force: true })
247
+ .then(() => {
248
+ expect(fn).to.be.called
249
+ })
250
+ cy.dataCy('menu')
251
+ .should('not.exist')
252
+ })
253
+ })
254
+ })
255
+
256
+ describe('Methods', () => {
257
+ describe('(method): show', () => {
258
+ it('should tigger the menu to show', () => {
259
+ mount(WrapperOne)
260
+
261
+ cy.dataCy('wrapper')
262
+ cy.dataCy('method-show')
263
+ .click({ force: true })
264
+ cy.dataCy('menu')
265
+ .should('exist')
266
+ })
267
+ })
268
+
269
+ describe('(method): hide', () => {
270
+ it('should tigger the menu to hide', () => {
271
+ mount(WrapperOne)
272
+
273
+ cy.dataCy('wrapper')
274
+ .click()
275
+ cy.dataCy('menu')
276
+ .should('exist')
277
+ cy.dataCy('method-hide')
278
+ .click({ force: true })
279
+ cy.dataCy('menu')
280
+ .should('not.exist')
281
+ })
282
+ })
283
+
284
+ describe('(method): toggle', () => {
285
+ it('should toggle the menu', () => {
286
+ mount(WrapperTwo)
287
+
288
+ cy.dataCy('wrapper')
289
+ .then(() => {
290
+ // Need to call method from wrapper
291
+ // Click a button closes the menu
292
+ Cypress.vueWrapper.vm.toggle()
293
+ })
294
+ cy.dataCy('menu')
295
+ .should('exist')
296
+ .then(() => {
297
+ // Need to call method from wrapper
298
+ // Click a button closes the menu
299
+ Cypress.vueWrapper.vm.toggle()
300
+ })
301
+ cy.dataCy('menu')
302
+ .should('not.exist')
303
+ })
304
+ })
305
+ })
306
+ })
@@ -0,0 +1,4 @@
1
+ describe('use-portal API', () => {
2
+ describe('Props', () => {
3
+ })
4
+ })
@@ -0,0 +1,55 @@
1
+ describe('use-router-link API', () => {
2
+ describe('Props', () => {
3
+ describe('Category: navigation', () => {
4
+ describe('(prop): to', () => {
5
+ it.skip(' ', () => {
6
+ //
7
+ })
8
+ })
9
+
10
+ describe('(prop): exact', () => {
11
+ it.skip(' ', () => {
12
+ //
13
+ })
14
+ })
15
+
16
+ describe('(prop): replace', () => {
17
+ it.skip(' ', () => {
18
+ //
19
+ })
20
+ })
21
+
22
+ describe('(prop): active-class', () => {
23
+ it.skip(' ', () => {
24
+ //
25
+ })
26
+ })
27
+
28
+ describe('(prop): exact-active-class', () => {
29
+ it.skip(' ', () => {
30
+ //
31
+ })
32
+ })
33
+
34
+ describe('(prop): href', () => {
35
+ it.skip(' ', () => {
36
+ //
37
+ })
38
+ })
39
+
40
+ describe('(prop): target', () => {
41
+ it.skip(' ', () => {
42
+ //
43
+ })
44
+ })
45
+ })
46
+
47
+ describe('Category: state', () => {
48
+ describe('(prop): disable', () => {
49
+ it.skip(' ', () => {
50
+ //
51
+ })
52
+ })
53
+ })
54
+ })
55
+ })
@@ -0,0 +1,37 @@
1
+ import QAvatar from './../../../components/avatar/QAvatar'
2
+ import { mount } from '@cypress/vue'
3
+ import { useSizeDefaults } from './../use-size'
4
+
5
+ describe('use-size API', () => {
6
+ describe('Props', () => {
7
+ describe('Category: style', () => {
8
+ describe('(prop): size', () => {
9
+ it('should set the size', () => {
10
+ const size = '24px'
11
+ mount(QAvatar, {
12
+ props: {
13
+ size,
14
+ color: 'grey'
15
+ }
16
+ })
17
+
18
+ cy.get('.q-avatar')
19
+ .should('have.css', 'font-size', size)
20
+ })
21
+
22
+ it('should set the size with standard size names', () => {
23
+ const size = 'sm'
24
+ mount(QAvatar, {
25
+ props: {
26
+ size,
27
+ color: 'grey'
28
+ }
29
+ })
30
+
31
+ cy.get('.q-avatar')
32
+ .should('have.css', 'font-size', `${ useSizeDefaults.sm }px`)
33
+ })
34
+ })
35
+ })
36
+ })
37
+ })
@@ -0,0 +1,108 @@
1
+ import { mount } from '@cypress/vue'
2
+ import WrapperOne from './../../../components/menu/__tests__/WrapperOne.vue'
3
+
4
+ describe('use-transition API', () => {
5
+ describe('Props', () => {
6
+ describe('Category: transition', () => {
7
+ describe('(prop): transition-show', () => {
8
+ it('should use the fade transition by default', () => {
9
+ mount(WrapperOne)
10
+ cy.dataCy('wrapper')
11
+ .click()
12
+ cy.dataCy('menu', { timeout: 0 }) // Disable retry
13
+ .should('have.class', 'q-transition--fade-enter-active')
14
+ })
15
+
16
+ it('should use a different show transtion if defined', () => {
17
+ const transition = 'scale'
18
+ mount(WrapperOne, {
19
+ attrs: {
20
+ transitionShow: transition
21
+ }
22
+ })
23
+ cy.dataCy('wrapper')
24
+ .click()
25
+ cy.dataCy('menu', { timeout: 0 }) // Disable retry
26
+ .should('have.class', `q-transition--${ transition }-enter-active`)
27
+ })
28
+ })
29
+
30
+ describe('(prop): transition-hide', () => {
31
+ it('should use the fade transition by default', () => {
32
+ mount(WrapperOne)
33
+ cy.dataCy('wrapper')
34
+ .click()
35
+ cy.dataCy('menu')
36
+ .should('exist')
37
+ cy.get('body')
38
+ .type('{esc}')
39
+ cy.dataCy('menu', { timeout: 0 }) // Disable retry
40
+ .should('have.class', 'q-transition--fade-leave-active')
41
+ })
42
+
43
+ it('should use a different hide transtion if defined', () => {
44
+ const transition = 'scale'
45
+ mount(WrapperOne, {
46
+ attrs: {
47
+ transitionHide: transition
48
+ }
49
+ })
50
+ cy.dataCy('wrapper')
51
+ .click()
52
+ cy.dataCy('menu')
53
+ .should('exist')
54
+ cy.get('body')
55
+ .type('{esc}')
56
+ cy.dataCy('menu', { timeout: 0 }) // Disable retry
57
+ .should('have.class', `q-transition--${ transition }-leave-active`)
58
+ })
59
+ })
60
+
61
+ describe('(prop): transition-duration', () => {
62
+ it('should be done with transitioning after 300ms passed', () => {
63
+ mount(WrapperOne)
64
+ cy.dataCy('wrapper')
65
+ .click()
66
+ .wait(300)
67
+ cy.dataCy('menu', { timeout: 0 }) // Disable retry
68
+ .should('not.have.class', 'q-transition--fade-enter-active')
69
+ })
70
+
71
+ it('should not be done with transitioning before 300ms passed', () => {
72
+ mount(WrapperOne)
73
+ cy.dataCy('wrapper')
74
+ .click()
75
+ .wait(200) // Commands take some time so a high value can fail, just take a decent margin
76
+ cy.dataCy('menu', { timeout: 0 }) // Disable retry
77
+ .should('have.class', 'q-transition--fade-enter-active')
78
+ })
79
+
80
+ it('should be done after a custom 1000ms passed', () => {
81
+ mount(WrapperOne, {
82
+ attrs: {
83
+ transitionDuration: 1000
84
+ }
85
+ })
86
+ cy.dataCy('wrapper')
87
+ .click()
88
+ .wait(1000)
89
+ cy.dataCy('menu', { timeout: 0 }) // Disable retry
90
+ .should('not.have.class', 'q-transition--fade-enter-active')
91
+ })
92
+
93
+ it('should not be done before a custom 1000ms passed', () => {
94
+ mount(WrapperOne, {
95
+ attrs: {
96
+ transitionDuration: 1000
97
+ }
98
+ })
99
+ cy.dataCy('wrapper')
100
+ .click()
101
+ .wait(900)
102
+ cy.dataCy('menu', { timeout: 0 }) // Disable retry
103
+ .should('have.class', 'q-transition--fade-enter-active')
104
+ })
105
+ })
106
+ })
107
+ })
108
+ })
@@ -0,0 +1,111 @@
1
+ import { mount } from '@cypress/vue'
2
+ import FieldWrapper from './FieldWrapper.vue'
3
+ import Icons from './../../../../icon-set/material-icons'
4
+
5
+ // const snapshotOptions = { customSnapshotsDir: '../__tests__' }
6
+
7
+ describe('use-validate API', () => {
8
+ describe('Props', () => {
9
+ describe('Category: behavior', () => {
10
+ describe('(prop): error', () => {
11
+ it.skip(' ', () => {
12
+ //
13
+ })
14
+ })
15
+
16
+ describe('(prop): rules', () => {
17
+ it.skip(' ', () => {
18
+ //
19
+ })
20
+ })
21
+
22
+ describe('(prop): reactive-rules', () => {
23
+ it.skip(' ', () => {
24
+ //
25
+ })
26
+ })
27
+
28
+ describe('(prop): lazy-rules', () => {
29
+ it.skip(' ', () => {
30
+ //
31
+ })
32
+ })
33
+ })
34
+
35
+ describe('Category: content', () => {
36
+ describe('(prop): error-message', () => {
37
+ it('should show an error-message when error is true', () => {
38
+ const message = 'Please select something'
39
+ mount(FieldWrapper, {
40
+ attrs: {
41
+ error: true,
42
+ errorMessage: message
43
+ }
44
+ })
45
+ cy.get('.select-root')
46
+ .should('include.text', message)
47
+ })
48
+
49
+ it('should not show an error-message when error is false', () => {
50
+ const message = 'Please select something'
51
+ mount(FieldWrapper, {
52
+ attrs: {
53
+ error: false,
54
+ errorMessage: message
55
+ }
56
+ })
57
+ cy.get('.select-root')
58
+ .should('not.include.text', message)
59
+ })
60
+ })
61
+
62
+ describe('(prop): no-error-icon', () => {
63
+ it('should not show an error icon when error is true', () => {
64
+ mount(FieldWrapper, {
65
+ attrs: {
66
+ error: true,
67
+ noErrorIcon: true
68
+ }
69
+ })
70
+ cy.get('.select-root')
71
+ .get(`i:contains(${ Icons.field.error })`)
72
+ .should('not.exist')
73
+ })
74
+
75
+ it('should show an error icon when error is true an no-error-icon is false', () => {
76
+ mount(FieldWrapper, {
77
+ attrs: {
78
+ error: true,
79
+ noErrorIcon: false
80
+ }
81
+ })
82
+ cy.get('.select-root')
83
+ .get(`i:contains(${ Icons.field.error })`)
84
+ .should('exist')
85
+ })
86
+ })
87
+ })
88
+
89
+ describe('Category: model', () => {
90
+ describe('(prop): model-value', () => {
91
+ it.skip(' ', () => {
92
+ //
93
+ })
94
+ })
95
+ })
96
+ })
97
+
98
+ describe('Methods', () => {
99
+ describe('(method): resetValidation', () => {
100
+ it.skip(' ', () => {
101
+ //
102
+ })
103
+ })
104
+
105
+ describe('(method): validate', () => {
106
+ it.skip(' ', () => {
107
+ //
108
+ })
109
+ })
110
+ })
111
+ })
@@ -19,7 +19,7 @@ export default function () {
19
19
  let historyEntry, fullscreenFillerNode, container
20
20
  const inFullscreen = ref(false)
21
21
 
22
- vmHasRouter(vm) === true && watch(() => proxy.$route, () => {
22
+ vmHasRouter(vm) === true && watch(() => proxy.$route.fullPath, () => {
23
23
  props.noRouteFullscreenExit !== true && exitFullscreen()
24
24
  })
25
25
 
@@ -136,7 +136,7 @@ export default function ({
136
136
  watch(() => props.modelValue, processModelChange)
137
137
 
138
138
  if (hideOnRouteChange !== void 0 && vmHasRouter(vm) === true) {
139
- watch(() => proxy.$route, () => {
139
+ watch(() => proxy.$route.fullPath, () => {
140
140
  if (hideOnRouteChange.value === true && showing.value === true) {
141
141
  hide()
142
142
  }
@@ -37,12 +37,16 @@ export default function (focused, innerLoading) {
37
37
  let validateIndex = 0, unwatchRules
38
38
 
39
39
  const hasRules = computed(() =>
40
- props.disable !== true
41
- && props.rules !== void 0
40
+ props.rules !== void 0
42
41
  && props.rules !== null
43
42
  && props.rules.length > 0
44
43
  )
45
44
 
45
+ const hasActiveRules = computed(() =>
46
+ props.disable !== true
47
+ && hasRules.value === true
48
+ )
49
+
46
50
  const hasError = computed(() =>
47
51
  props.error === true || innerError.value === true
48
52
  )
@@ -80,7 +84,7 @@ export default function (focused, innerLoading) {
80
84
  else if (isDirtyModel.value === false) {
81
85
  isDirtyModel.value = true
82
86
 
83
- if (hasRules.value === true && props.lazyRules !== 'ondemand') {
87
+ if (hasActiveRules.value === true && props.lazyRules !== 'ondemand') {
84
88
  debouncedValidate()
85
89
  }
86
90
  }
@@ -102,7 +106,7 @@ export default function (focused, innerLoading) {
102
106
  * - Promise (pending async validation)
103
107
  */
104
108
  function validate (val = props.modelValue) {
105
- if (hasRules.value !== true) {
109
+ if (hasActiveRules.value !== true) {
106
110
  return true
107
111
  }
108
112
 
@@ -190,7 +194,7 @@ export default function (focused, innerLoading) {
190
194
 
191
195
  function validateIfNeeded (changedRules) {
192
196
  if (
193
- hasRules.value === true
197
+ hasActiveRules.value === true
194
198
  && props.lazyRules !== 'ondemand'
195
199
  && (isDirtyModel.value === true || (props.lazyRules !== true && changedRules !== true))
196
200
  ) {
@@ -140,7 +140,7 @@ function apply ({ add, remove }) {
140
140
  function getAttr (seed) {
141
141
  return att => {
142
142
  const val = seed[ att ]
143
- return att + (val !== void 0 ? `="${ val }"` : '')
143
+ return att + (val !== true && val !== void 0 ? `="${ val }"` : '')
144
144
  }
145
145
  }
146
146