quasar 2.12.6 → 2.13.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 (141) hide show
  1. package/dist/api/QField.json +0 -3
  2. package/dist/api/QSelect.json +1 -1
  3. package/dist/api/QTable.json +54 -1
  4. package/dist/icon-set/bootstrap-icons.umd.prod.js +1 -1
  5. package/dist/icon-set/eva-icons.umd.prod.js +1 -1
  6. package/dist/icon-set/fontawesome-v5-pro.umd.prod.js +1 -1
  7. package/dist/icon-set/fontawesome-v5.umd.prod.js +1 -1
  8. package/dist/icon-set/fontawesome-v6-pro.umd.prod.js +1 -1
  9. package/dist/icon-set/fontawesome-v6.umd.prod.js +1 -1
  10. package/dist/icon-set/ionicons-v4.umd.prod.js +1 -1
  11. package/dist/icon-set/line-awesome.umd.prod.js +1 -1
  12. package/dist/icon-set/material-icons-outlined.umd.prod.js +1 -1
  13. package/dist/icon-set/material-icons-round.umd.prod.js +1 -1
  14. package/dist/icon-set/material-icons-sharp.umd.prod.js +1 -1
  15. package/dist/icon-set/material-icons.umd.prod.js +1 -1
  16. package/dist/icon-set/material-symbols-outlined.umd.prod.js +1 -1
  17. package/dist/icon-set/material-symbols-rounded.umd.prod.js +1 -1
  18. package/dist/icon-set/material-symbols-sharp.umd.prod.js +1 -1
  19. package/dist/icon-set/mdi-v3.umd.prod.js +1 -1
  20. package/dist/icon-set/mdi-v4.umd.prod.js +1 -1
  21. package/dist/icon-set/mdi-v5.umd.prod.js +1 -1
  22. package/dist/icon-set/mdi-v6.umd.prod.js +1 -1
  23. package/dist/icon-set/mdi-v7.umd.prod.js +1 -1
  24. package/dist/icon-set/svg-bootstrap-icons.umd.prod.js +1 -1
  25. package/dist/icon-set/svg-eva-icons.umd.prod.js +1 -1
  26. package/dist/icon-set/svg-fontawesome-v5.umd.prod.js +1 -1
  27. package/dist/icon-set/svg-fontawesome-v6.umd.prod.js +1 -1
  28. package/dist/icon-set/svg-ionicons-v4.umd.prod.js +1 -1
  29. package/dist/icon-set/svg-ionicons-v5.umd.prod.js +1 -1
  30. package/dist/icon-set/svg-ionicons-v6.umd.prod.js +1 -1
  31. package/dist/icon-set/svg-line-awesome.umd.prod.js +1 -1
  32. package/dist/icon-set/svg-material-icons-outlined.umd.prod.js +2 -2
  33. package/dist/icon-set/svg-material-icons-round.umd.prod.js +2 -2
  34. package/dist/icon-set/svg-material-icons-sharp.umd.prod.js +2 -2
  35. package/dist/icon-set/svg-material-icons.umd.prod.js +2 -2
  36. package/dist/icon-set/svg-material-symbols-outlined.umd.prod.js +2 -2
  37. package/dist/icon-set/svg-material-symbols-rounded.umd.prod.js +2 -2
  38. package/dist/icon-set/svg-material-symbols-sharp.umd.prod.js +2 -2
  39. package/dist/icon-set/svg-mdi-v6.umd.prod.js +1 -1
  40. package/dist/icon-set/svg-mdi-v7.umd.prod.js +1 -1
  41. package/dist/icon-set/svg-themify.umd.prod.js +1 -1
  42. package/dist/icon-set/themify.umd.prod.js +1 -1
  43. package/dist/lang/ar-TN.umd.prod.js +1 -1
  44. package/dist/lang/ar.umd.prod.js +1 -1
  45. package/dist/lang/az-Latn.umd.prod.js +1 -1
  46. package/dist/lang/bg.umd.prod.js +1 -1
  47. package/dist/lang/bn.umd.prod.js +1 -1
  48. package/dist/lang/ca.umd.prod.js +1 -1
  49. package/dist/lang/cs.umd.prod.js +1 -1
  50. package/dist/lang/da.umd.prod.js +1 -1
  51. package/dist/lang/de-CH.umd.prod.js +6 -0
  52. package/dist/lang/de-DE.umd.prod.js +6 -0
  53. package/dist/lang/de.umd.prod.js +1 -1
  54. package/dist/lang/el.umd.prod.js +1 -1
  55. package/dist/lang/en-GB.umd.prod.js +1 -1
  56. package/dist/lang/en-US.umd.prod.js +1 -1
  57. package/dist/lang/eo.umd.prod.js +1 -1
  58. package/dist/lang/es.umd.prod.js +1 -1
  59. package/dist/lang/et.umd.prod.js +1 -1
  60. package/dist/lang/eu.umd.prod.js +1 -1
  61. package/dist/lang/fa-IR.umd.prod.js +1 -1
  62. package/dist/lang/fa.umd.prod.js +1 -1
  63. package/dist/lang/fi.umd.prod.js +1 -1
  64. package/dist/lang/fr.umd.prod.js +1 -1
  65. package/dist/lang/gn.umd.prod.js +1 -1
  66. package/dist/lang/he.umd.prod.js +1 -1
  67. package/dist/lang/hi.umd.prod.js +1 -1
  68. package/dist/lang/hr.umd.prod.js +1 -1
  69. package/dist/lang/hu.umd.prod.js +1 -1
  70. package/dist/lang/id.umd.prod.js +1 -1
  71. package/dist/lang/is.umd.prod.js +1 -1
  72. package/dist/lang/it.umd.prod.js +1 -1
  73. package/dist/lang/ja.umd.prod.js +1 -1
  74. package/dist/lang/kk.umd.prod.js +1 -1
  75. package/dist/lang/km.umd.prod.js +1 -1
  76. package/dist/lang/ko-KR.umd.prod.js +1 -1
  77. package/dist/lang/kur-CKB.umd.prod.js +1 -1
  78. package/dist/lang/lt.umd.prod.js +1 -1
  79. package/dist/lang/lu.umd.prod.js +1 -1
  80. package/dist/lang/lv.umd.prod.js +1 -1
  81. package/dist/lang/mk.umd.prod.js +1 -1
  82. package/dist/lang/ml.umd.prod.js +1 -1
  83. package/dist/lang/mm.umd.prod.js +1 -1
  84. package/dist/lang/ms.umd.prod.js +1 -1
  85. package/dist/lang/my.umd.prod.js +1 -1
  86. package/dist/lang/nb-NO.umd.prod.js +1 -1
  87. package/dist/lang/nl.umd.prod.js +1 -1
  88. package/dist/lang/pl.umd.prod.js +1 -1
  89. package/dist/lang/pt-BR.umd.prod.js +1 -1
  90. package/dist/lang/pt.umd.prod.js +1 -1
  91. package/dist/lang/ro.umd.prod.js +1 -1
  92. package/dist/lang/ru.umd.prod.js +1 -1
  93. package/dist/lang/sk.umd.prod.js +1 -1
  94. package/dist/lang/sl.umd.prod.js +1 -1
  95. package/dist/lang/sm.umd.prod.js +1 -1
  96. package/dist/lang/sr-CYR.umd.prod.js +1 -1
  97. package/dist/lang/sr.umd.prod.js +1 -1
  98. package/dist/lang/sv.umd.prod.js +1 -1
  99. package/dist/lang/ta.umd.prod.js +1 -1
  100. package/dist/lang/th.umd.prod.js +1 -1
  101. package/dist/lang/tr.umd.prod.js +1 -1
  102. package/dist/lang/ug.umd.prod.js +1 -1
  103. package/dist/lang/uk.umd.prod.js +1 -1
  104. package/dist/lang/uz-Cyrl.umd.prod.js +1 -1
  105. package/dist/lang/uz-Latn.umd.prod.js +1 -1
  106. package/dist/lang/vi.umd.prod.js +1 -1
  107. package/dist/lang/zh-CN.umd.prod.js +1 -1
  108. package/dist/lang/zh-TW.umd.prod.js +1 -1
  109. package/dist/quasar.addon.prod.css +1 -1
  110. package/dist/quasar.addon.rtl.prod.css +1 -1
  111. package/dist/quasar.cjs.prod.js +2 -2
  112. package/dist/quasar.esm.js +122 -48
  113. package/dist/quasar.esm.prod.js +2 -2
  114. package/dist/quasar.prod.css +1 -1
  115. package/dist/quasar.rtl.prod.css +1 -1
  116. package/dist/quasar.sass +1 -1
  117. package/dist/quasar.umd.js +122 -48
  118. package/dist/quasar.umd.prod.js +2 -2
  119. package/dist/types/index.d.ts +13 -3
  120. package/dist/vetur/quasar-attributes.json +1 -1
  121. package/dist/web-types/web-types.json +2 -6
  122. package/lang/de-CH.js +98 -0
  123. package/lang/de-CH.mjs +93 -0
  124. package/lang/de-DE.js +98 -0
  125. package/lang/de-DE.mjs +93 -0
  126. package/lang/index.json +8 -0
  127. package/package.json +4 -3
  128. package/src/components/field/__tests__/QField.cy.js +156 -0
  129. package/src/components/input/use-mask.js +6 -1
  130. package/src/components/scroll-area/QScrollArea.js +16 -1
  131. package/src/components/select/QSelect.js +42 -17
  132. package/src/components/select/QSelect.json +1 -1
  133. package/src/components/select/__tests__/QSelect.cy.js +2 -1
  134. package/src/components/slider/use-slider.js +13 -12
  135. package/src/components/table/QTable.json +38 -1
  136. package/src/components/table/table-sort.js +5 -0
  137. package/src/components/time/QTime.js +16 -3
  138. package/src/components/tree/QTree.js +22 -12
  139. package/src/composables/private/__tests__/FieldWrapper.vue +17 -2
  140. package/src/composables/private/__tests__/use-field.cy.js +334 -137
  141. package/src/composables/private/__tests__/use-validate.cy.js +162 -15
@@ -1,32 +1,118 @@
1
1
  import FieldWrapper from './FieldWrapper.vue'
2
2
  import Icons from '../../../../icon-set/material-icons.mjs'
3
+ import { ref } from 'vue'
4
+ import { vModelAdapter } from '@quasar/quasar-app-extension-testing-e2e-cypress'
3
5
 
4
- // const snapshotOptions = { customSnapshotsDir: '../__tests__' }
6
+ function mountQFieldWrapper (options) {
7
+ return cy.mount(FieldWrapper, options)
8
+ }
9
+
10
+ function getHostElement () {
11
+ return cy.get('.select-root')
12
+ }
5
13
 
6
14
  describe('use-validate API', () => {
7
15
  describe('Props', () => {
8
16
  describe('Category: behavior', () => {
9
17
  describe('(prop): error', () => {
10
- it.skip(' ', () => {
11
- //
18
+ it('should mark the field as having an error', () => {
19
+ mountQFieldWrapper()
20
+ getHostElement().should('not.have.class', 'q-field--error')
21
+
22
+ getHostElement().then(() => {
23
+ Cypress.vueWrapper.setProps({ error: true })
24
+ })
25
+
26
+ getHostElement().should('have.class', 'q-field--error')
12
27
  })
13
28
  })
14
29
 
15
30
  describe('(prop): rules', () => {
16
- it.skip(' ', () => {
17
- //
31
+ it('should validate value using custom validation logic', () => {
32
+ const errorMessage = 'Selected value should be greater than 10 characters'
33
+ const model = ref('Option 1')
34
+ const options = [ 'Option 1', 'Option 2' ]
35
+
36
+ mountQFieldWrapper({
37
+ props: {
38
+ ...vModelAdapter(model),
39
+ options,
40
+ rules: [ val => val.length > 10 || errorMessage ]
41
+ }
42
+ })
43
+
44
+ getHostElement().then(() => {
45
+ model.value = 'Option 2'
46
+ })
47
+ getHostElement().get('.q-field__messages').should('contain.text', errorMessage)
48
+ })
49
+
50
+ it('should validate email using inbuilt validation logic', () => {
51
+ const errorMessage = 'Enter a valid email address'
52
+ const model = ref('Option 1')
53
+ const options = [ 'Option 1', 'Option 2' ]
54
+ mountQFieldWrapper({
55
+ props: {
56
+ ...vModelAdapter(model),
57
+ options,
58
+ rules: [ (val, rules) => rules.email(val) || errorMessage ]
59
+ }
60
+ })
61
+ getHostElement().then(() => {
62
+ model.value = 'Option 2'
63
+ })
64
+ getHostElement().get('.q-field__messages').should('contain.text', errorMessage)
18
65
  })
19
66
  })
20
67
 
21
68
  describe('(prop): reactive-rules', () => {
22
- it.skip(' ', () => {
23
- //
69
+ it('should trigger validation when there\'s a change of rules', () => {
70
+ const errorMessage = 'Error message'
71
+ const model = ref('Option 1')
72
+ const options = [ 'Option 1', 'Option 2' ]
73
+ mountQFieldWrapper({
74
+ props: {
75
+ ...vModelAdapter(model),
76
+ options
77
+ }
78
+ })
79
+
80
+ getHostElement().then(() => {
81
+ Cypress.vueWrapper.setProps({ rules: [ (value) => value.length < 3 || errorMessage ] })
82
+
83
+ Cypress.vueWrapper.vm.focusMethod()
84
+ Cypress.vueWrapper.vm.blur()
85
+ })
86
+ getHostElement().get('.q-field__messages').should('not.exist')
87
+
88
+ getHostElement().then(() => {
89
+ Cypress.vueWrapper.setProps({ reactiveRules: true, rules: [ (value, rules) => rules.email(value) || errorMessage ] })
90
+ })
91
+ getHostElement().get('.q-field__messages').should('contain.text', errorMessage)
24
92
  })
25
93
  })
26
94
 
27
95
  describe('(prop): lazy-rules', () => {
28
- it.skip(' ', () => {
29
- //
96
+ it('should validate the input only when component loses focus', () => {
97
+ const errorMessage = 'Use a max 3 of characters'
98
+ const model = ref('Option 1')
99
+ const options = [ 'Option 1', 'Option 2' ]
100
+ mountQFieldWrapper({
101
+ props: {
102
+ ...vModelAdapter(model),
103
+ options,
104
+ lazyRules: true,
105
+ rules: [ () => errorMessage ]
106
+ }
107
+ })
108
+
109
+ getHostElement().select('Option 2')
110
+ getHostElement().get('.q-field__messages').should('not.contain', errorMessage)
111
+
112
+ getHostElement().then(() => {
113
+ Cypress.vueWrapper.vm.blur()
114
+ getHostElement().get('.q-field__messages').should('contain.text', errorMessage)
115
+ })
30
116
  })
31
117
  })
32
118
  })
@@ -87,8 +173,22 @@ describe('use-validate API', () => {
87
173
 
88
174
  describe('Category: model', () => {
89
175
  describe('(prop): model-value', () => {
90
- it.skip(' ', () => {
91
- //
176
+ it('should correctly update the model value', () => {
177
+ const model = ref()
178
+ const options = [ 'Option 1', 'Option 2' ]
179
+ mountQFieldWrapper({
180
+ props: {
181
+ ...vModelAdapter(model),
182
+ options
183
+ }
184
+ })
185
+ getHostElement().get('input').should('not.have.value', options[ 0 ])
186
+
187
+ getHostElement().then(() => {
188
+ model.value = options[ 0 ]
189
+ })
190
+
191
+ getHostElement().get('input').should('have.value', options[ 0 ])
92
192
  })
93
193
  })
94
194
  })
@@ -96,14 +196,61 @@ describe('use-validate API', () => {
96
196
 
97
197
  describe('Methods', () => {
98
198
  describe('(method): resetValidation', () => {
99
- it.skip(' ', () => {
100
- //
199
+ it('should reset validation', () => {
200
+ const errorMessage = 'Use a max 3 of characters'
201
+ const model = ref('Option 1')
202
+ const options = [ 'Option 1', 'Option 2' ]
203
+ mountQFieldWrapper({
204
+ props: {
205
+ ...vModelAdapter(model),
206
+ options,
207
+ rules: [ val => val.length <= 3 || errorMessage ],
208
+ lazyRules: 'ondemand'
209
+ }
210
+ })
211
+
212
+ getHostElement().then(() => {
213
+ model.value = 'Option 2'
214
+ })
215
+ getHostElement().get('.q-field__messages').should('not.contain', errorMessage)
216
+
217
+ getHostElement().then(() => {
218
+ Cypress.vueWrapper.vm.validate()
219
+ getHostElement().get('.q-field__messages').should('contain', errorMessage)
220
+ })
221
+
222
+ getHostElement().then(() => {
223
+ Cypress.vueWrapper.vm.resetValidation()
224
+ getHostElement().get('.q-field__messages').should('not.contain', errorMessage)
225
+ })
101
226
  })
102
227
  })
103
228
 
104
229
  describe('(method): validate', () => {
105
- it.skip(' ', () => {
106
- //
230
+ it('should validate the input only when component\'s validate() method is called', () => {
231
+ const errorMessage = 'Use a max 3 of characters'
232
+ const model = ref('Option 1')
233
+ const options = [ 'Option 1', 'Option 2' ]
234
+ mountQFieldWrapper({
235
+ props: {
236
+ ...vModelAdapter(model),
237
+ options,
238
+ rules: [ val => val.length <= 3 || errorMessage ],
239
+ lazyRules: 'ondemand'
240
+ }
241
+ })
242
+
243
+ getHostElement().then(() => {
244
+ model.value = 'Option 2'
245
+ })
246
+ getHostElement().get('.q-field__messages').should('not.contain', errorMessage)
247
+
248
+ getHostElement().get('input').then(() => {
249
+ Cypress.vueWrapper.vm.blur()
250
+ getHostElement().get('.q-field__messages').should('not.contain', errorMessage)
251
+ Cypress.vueWrapper.vm.validate()
252
+ getHostElement().get('.q-field__messages').should('contain', errorMessage)
253
+ })
107
254
  })
108
255
  })
109
256
  })