quasar 2.8.3 → 2.8.4

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 (274) hide show
  1. package/dist/api/QBtnDropdown.json +9 -0
  2. package/dist/api/QChip.json +9 -0
  3. package/dist/api/QCircularProgress.json +6 -0
  4. package/dist/api/QExpansionItem.json +59 -0
  5. package/dist/api/QTable.json +2 -2
  6. package/dist/icon-set/bootstrap-icons.umd.prod.js +1 -1
  7. package/dist/icon-set/eva-icons.umd.prod.js +1 -1
  8. package/dist/icon-set/fontawesome-v5-pro.umd.prod.js +1 -1
  9. package/dist/icon-set/fontawesome-v5.umd.prod.js +1 -1
  10. package/dist/icon-set/fontawesome-v6-pro.umd.prod.js +1 -1
  11. package/dist/icon-set/fontawesome-v6.umd.prod.js +1 -1
  12. package/dist/icon-set/ionicons-v4.umd.prod.js +1 -1
  13. package/dist/icon-set/line-awesome.umd.prod.js +1 -1
  14. package/dist/icon-set/material-icons-outlined.umd.prod.js +1 -1
  15. package/dist/icon-set/material-icons-round.umd.prod.js +1 -1
  16. package/dist/icon-set/material-icons-sharp.umd.prod.js +1 -1
  17. package/dist/icon-set/material-icons.umd.prod.js +1 -1
  18. package/dist/icon-set/material-symbols-outlined.umd.prod.js +1 -1
  19. package/dist/icon-set/material-symbols-rounded.umd.prod.js +1 -1
  20. package/dist/icon-set/material-symbols-sharp.umd.prod.js +1 -1
  21. package/dist/icon-set/mdi-v3.umd.prod.js +1 -1
  22. package/dist/icon-set/mdi-v4.umd.prod.js +1 -1
  23. package/dist/icon-set/mdi-v5.umd.prod.js +1 -1
  24. package/dist/icon-set/mdi-v6.umd.prod.js +1 -1
  25. package/dist/icon-set/svg-bootstrap-icons.umd.prod.js +1 -1
  26. package/dist/icon-set/svg-eva-icons.umd.prod.js +1 -1
  27. package/dist/icon-set/svg-fontawesome-v5.umd.prod.js +1 -1
  28. package/dist/icon-set/svg-fontawesome-v6.umd.prod.js +1 -1
  29. package/dist/icon-set/svg-ionicons-v4.umd.prod.js +1 -1
  30. package/dist/icon-set/svg-ionicons-v5.umd.prod.js +1 -1
  31. package/dist/icon-set/svg-ionicons-v6.umd.prod.js +1 -1
  32. package/dist/icon-set/svg-line-awesome.umd.prod.js +1 -1
  33. package/dist/icon-set/svg-material-icons-outlined.umd.prod.js +1 -1
  34. package/dist/icon-set/svg-material-icons-round.umd.prod.js +1 -1
  35. package/dist/icon-set/svg-material-icons-sharp.umd.prod.js +1 -1
  36. package/dist/icon-set/svg-material-icons.umd.prod.js +1 -1
  37. package/dist/icon-set/svg-material-symbols-outlined.umd.prod.js +1 -1
  38. package/dist/icon-set/svg-material-symbols-rounded.umd.prod.js +1 -1
  39. package/dist/icon-set/svg-material-symbols-sharp.umd.prod.js +1 -1
  40. package/dist/icon-set/svg-mdi-v6.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 +2 -2
  44. package/dist/lang/ar.umd.prod.js +2 -2
  45. package/dist/lang/az-Latn.umd.prod.js +2 -2
  46. package/dist/lang/bg.umd.prod.js +2 -2
  47. package/dist/lang/bn.umd.prod.js +2 -2
  48. package/dist/lang/ca.umd.prod.js +2 -2
  49. package/dist/lang/cs.umd.prod.js +2 -2
  50. package/dist/lang/da.umd.prod.js +2 -2
  51. package/dist/lang/de.umd.prod.js +2 -2
  52. package/dist/lang/el.umd.prod.js +2 -2
  53. package/dist/lang/en-GB.umd.prod.js +2 -2
  54. package/dist/lang/en-US.umd.prod.js +2 -2
  55. package/dist/lang/eo.umd.prod.js +2 -2
  56. package/dist/lang/es.umd.prod.js +2 -2
  57. package/dist/lang/et.umd.prod.js +2 -2
  58. package/dist/lang/eu.umd.prod.js +2 -2
  59. package/dist/lang/fa-IR.umd.prod.js +2 -2
  60. package/dist/lang/fa.umd.prod.js +2 -2
  61. package/dist/lang/fi.umd.prod.js +2 -2
  62. package/dist/lang/fr.umd.prod.js +2 -2
  63. package/dist/lang/gn.umd.prod.js +2 -2
  64. package/dist/lang/he.umd.prod.js +2 -2
  65. package/dist/lang/hr.umd.prod.js +2 -2
  66. package/dist/lang/hu.umd.prod.js +2 -2
  67. package/dist/lang/id.umd.prod.js +2 -2
  68. package/dist/lang/is.umd.prod.js +2 -2
  69. package/dist/lang/it.umd.prod.js +2 -2
  70. package/dist/lang/ja.umd.prod.js +2 -2
  71. package/dist/lang/km.umd.prod.js +2 -2
  72. package/dist/lang/ko-KR.umd.prod.js +2 -2
  73. package/dist/lang/kur-CKB.umd.prod.js +2 -2
  74. package/dist/lang/kz.umd.prod.js +2 -2
  75. package/dist/lang/lt.umd.prod.js +2 -2
  76. package/dist/lang/lu.umd.prod.js +2 -2
  77. package/dist/lang/lv.umd.prod.js +2 -2
  78. package/dist/lang/ml.umd.prod.js +2 -2
  79. package/dist/lang/mm.umd.prod.js +2 -2
  80. package/dist/lang/ms.umd.prod.js +2 -2
  81. package/dist/lang/my.umd.prod.js +2 -2
  82. package/dist/lang/nb-NO.umd.prod.js +2 -2
  83. package/dist/lang/nl.umd.prod.js +2 -2
  84. package/dist/lang/pl.umd.prod.js +2 -2
  85. package/dist/lang/pt-BR.umd.prod.js +2 -2
  86. package/dist/lang/pt.umd.prod.js +2 -2
  87. package/dist/lang/ro.umd.prod.js +2 -2
  88. package/dist/lang/ru.umd.prod.js +2 -2
  89. package/dist/lang/sk.umd.prod.js +2 -2
  90. package/dist/lang/sl.umd.prod.js +2 -2
  91. package/dist/lang/sm.umd.prod.js +2 -2
  92. package/dist/lang/sr-CYR.umd.prod.js +2 -2
  93. package/dist/lang/sr.umd.prod.js +2 -2
  94. package/dist/lang/sv.umd.prod.js +2 -2
  95. package/dist/lang/ta.umd.prod.js +2 -2
  96. package/dist/lang/th.umd.prod.js +2 -2
  97. package/dist/lang/tr.umd.prod.js +2 -2
  98. package/dist/lang/ug.umd.prod.js +2 -2
  99. package/dist/lang/uk.umd.prod.js +2 -2
  100. package/dist/lang/uz-Cyrl.umd.prod.js +2 -2
  101. package/dist/lang/uz-Latn.umd.prod.js +2 -2
  102. package/dist/lang/vi.umd.prod.js +2 -2
  103. package/dist/lang/zh-CN.umd.prod.js +2 -2
  104. package/dist/lang/zh-TW.umd.prod.js +2 -2
  105. package/dist/quasar.cjs.prod.js +2 -2
  106. package/dist/quasar.esm.js +15693 -15455
  107. package/dist/quasar.esm.prod.js +2 -2
  108. package/dist/quasar.sass +1 -1
  109. package/dist/quasar.umd.js +15866 -15626
  110. package/dist/quasar.umd.prod.js +2 -2
  111. package/dist/transforms/import-map.json +2 -0
  112. package/dist/types/api/qloading.d.ts +5 -0
  113. package/dist/types/api.d.ts +1 -0
  114. package/dist/types/index.d.ts +40 -1
  115. package/dist/types/utils/is.d.ts +67 -0
  116. package/dist/types/utils/run-sequential-promises.d.ts +119 -0
  117. package/dist/types/utils.d.ts +9 -0
  118. package/dist/vetur/quasar-attributes.json +21 -1
  119. package/dist/vetur/quasar-tags.json +6 -1
  120. package/dist/web-types/web-types.json +49 -2
  121. package/lang/ar-TN.js +3 -1
  122. package/lang/ar-TN.mjs +3 -1
  123. package/lang/ar.js +3 -1
  124. package/lang/ar.mjs +3 -1
  125. package/lang/az-Latn.js +3 -1
  126. package/lang/az-Latn.mjs +3 -1
  127. package/lang/bg.js +3 -1
  128. package/lang/bg.mjs +3 -1
  129. package/lang/bn.js +3 -1
  130. package/lang/bn.mjs +3 -1
  131. package/lang/ca.js +3 -1
  132. package/lang/ca.mjs +3 -1
  133. package/lang/cs.js +3 -1
  134. package/lang/cs.mjs +3 -1
  135. package/lang/da.js +3 -1
  136. package/lang/da.mjs +3 -1
  137. package/lang/de.js +3 -1
  138. package/lang/de.mjs +3 -1
  139. package/lang/el.js +3 -1
  140. package/lang/el.mjs +3 -1
  141. package/lang/en-GB.js +3 -1
  142. package/lang/en-GB.mjs +3 -1
  143. package/lang/en-US.js +3 -1
  144. package/lang/en-US.mjs +3 -1
  145. package/lang/eo.js +3 -1
  146. package/lang/eo.mjs +3 -1
  147. package/lang/es.js +3 -1
  148. package/lang/es.mjs +3 -1
  149. package/lang/et.js +3 -1
  150. package/lang/et.mjs +3 -1
  151. package/lang/eu.js +3 -1
  152. package/lang/eu.mjs +3 -1
  153. package/lang/fa-IR.js +5 -3
  154. package/lang/fa-IR.mjs +5 -3
  155. package/lang/fa.js +5 -3
  156. package/lang/fa.mjs +5 -3
  157. package/lang/fi.js +3 -1
  158. package/lang/fi.mjs +3 -1
  159. package/lang/fr.js +3 -1
  160. package/lang/fr.mjs +3 -1
  161. package/lang/gn.js +3 -1
  162. package/lang/gn.mjs +3 -1
  163. package/lang/he.js +3 -1
  164. package/lang/he.mjs +3 -1
  165. package/lang/hr.js +3 -1
  166. package/lang/hr.mjs +3 -1
  167. package/lang/hu.js +3 -1
  168. package/lang/hu.mjs +3 -1
  169. package/lang/id.js +3 -1
  170. package/lang/id.mjs +3 -1
  171. package/lang/is.js +3 -1
  172. package/lang/is.mjs +3 -1
  173. package/lang/it.js +3 -1
  174. package/lang/it.mjs +3 -1
  175. package/lang/ja.js +3 -1
  176. package/lang/ja.mjs +3 -1
  177. package/lang/km.js +3 -1
  178. package/lang/km.mjs +3 -1
  179. package/lang/ko-KR.js +3 -1
  180. package/lang/ko-KR.mjs +3 -1
  181. package/lang/kur-CKB.js +3 -1
  182. package/lang/kur-CKB.mjs +3 -1
  183. package/lang/kz.js +3 -1
  184. package/lang/kz.mjs +3 -1
  185. package/lang/lt.js +3 -1
  186. package/lang/lt.mjs +3 -1
  187. package/lang/lu.js +3 -1
  188. package/lang/lu.mjs +3 -1
  189. package/lang/lv.js +3 -1
  190. package/lang/lv.mjs +3 -1
  191. package/lang/ml.js +3 -1
  192. package/lang/ml.mjs +3 -1
  193. package/lang/mm.js +4 -1
  194. package/lang/mm.mjs +4 -1
  195. package/lang/ms.js +3 -1
  196. package/lang/ms.mjs +3 -1
  197. package/lang/my.js +3 -1
  198. package/lang/my.mjs +3 -1
  199. package/lang/nb-NO.js +3 -1
  200. package/lang/nb-NO.mjs +3 -1
  201. package/lang/nl.js +3 -1
  202. package/lang/nl.mjs +3 -1
  203. package/lang/pl.js +3 -1
  204. package/lang/pl.mjs +3 -1
  205. package/lang/pt-BR.js +3 -1
  206. package/lang/pt-BR.mjs +3 -1
  207. package/lang/pt.js +3 -1
  208. package/lang/pt.mjs +3 -1
  209. package/lang/ro.js +3 -1
  210. package/lang/ro.mjs +3 -1
  211. package/lang/ru.js +3 -1
  212. package/lang/ru.mjs +3 -1
  213. package/lang/sk.js +3 -1
  214. package/lang/sk.mjs +3 -1
  215. package/lang/sl.js +3 -1
  216. package/lang/sl.mjs +3 -1
  217. package/lang/sm.js +3 -1
  218. package/lang/sm.mjs +3 -1
  219. package/lang/sr-CYR.js +3 -1
  220. package/lang/sr-CYR.mjs +3 -1
  221. package/lang/sr.js +3 -1
  222. package/lang/sr.mjs +3 -1
  223. package/lang/sv.js +3 -1
  224. package/lang/sv.mjs +3 -1
  225. package/lang/ta.js +3 -1
  226. package/lang/ta.mjs +3 -1
  227. package/lang/th.js +3 -1
  228. package/lang/th.mjs +3 -1
  229. package/lang/tr.js +3 -1
  230. package/lang/tr.mjs +3 -1
  231. package/lang/ug.js +5 -3
  232. package/lang/ug.mjs +5 -3
  233. package/lang/uk.js +3 -1
  234. package/lang/uk.mjs +3 -1
  235. package/lang/uz-Cyrl.js +3 -1
  236. package/lang/uz-Cyrl.mjs +3 -1
  237. package/lang/uz-Latn.js +3 -1
  238. package/lang/uz-Latn.mjs +3 -1
  239. package/lang/vi.js +3 -1
  240. package/lang/vi.mjs +3 -1
  241. package/lang/zh-CN.js +3 -1
  242. package/lang/zh-CN.mjs +3 -1
  243. package/lang/zh-TW.js +3 -1
  244. package/lang/zh-TW.mjs +3 -1
  245. package/package.json +4 -5
  246. package/src/components/btn-dropdown/QBtnDropdown.js +10 -2
  247. package/src/components/btn-dropdown/QBtnDropdown.json +8 -0
  248. package/src/components/chip/QChip.js +9 -2
  249. package/src/components/chip/QChip.json +8 -0
  250. package/src/components/chip/__tests__/QChip.spec.js +359 -46
  251. package/src/components/circular-progress/QCircularProgress.js +4 -2
  252. package/src/components/circular-progress/QCircularProgress.json +7 -0
  253. package/src/components/circular-progress/use-circular-progress.js +1 -0
  254. package/src/components/dialog/QDialog.js +1 -0
  255. package/src/components/expansion-item/QExpansionItem.js +37 -8
  256. package/src/components/expansion-item/QExpansionItem.json +67 -0
  257. package/src/components/fab/QFab.js +20 -1
  258. package/src/components/form/QForm.js +35 -40
  259. package/src/components/form/QFormChildMixin.js +3 -1
  260. package/src/components/menu/QMenu.js +1 -0
  261. package/src/components/page/QPage.js +1 -1
  262. package/src/components/select/QSelect.js +1 -4
  263. package/src/components/table/QTable.js +1 -1
  264. package/src/components/table/QTable.json +2 -2
  265. package/src/components/tabs/QTabs.js +2 -1
  266. package/src/components/time/QTime.js +2 -2
  267. package/src/components/uploader/uploader-core.js +2 -3
  268. package/src/composables/private/use-file.js +1 -1
  269. package/src/composables/private/use-validate.js +7 -13
  270. package/src/composables/use-form-child.js +6 -4
  271. package/src/utils/EventBus.js +64 -0
  272. package/src/utils/private/vm.js +4 -0
  273. package/src/utils/run-sequential-promises.js +115 -0
  274. package/src/utils.js +4 -0
@@ -1,125 +1,349 @@
1
+ import { mount } from '@cypress/vue'
2
+ import QChip, { defaultSizes } from '../QChip.js'
3
+
4
+ const defaultOptions = {
5
+ label: 'simple chip'
6
+ }
7
+
8
+ const chipSizeValues = Object.keys(defaultSizes)
9
+
10
+ function mountQChip (options = {}) {
11
+ options.props = {
12
+ ...defaultOptions,
13
+ ...options.props
14
+ }
15
+
16
+ return mount(QChip, options)
17
+ }
18
+
1
19
  describe('Chip API', () => {
2
20
  describe('Props', () => {
3
21
  describe('Category: content', () => {
4
22
  describe('(prop): icon', () => {
5
- it.skip(' ', () => {
6
- //
23
+ it('should render an icon on the left', () => {
24
+ const icon = 'add'
25
+
26
+ mountQChip({
27
+ props: {
28
+ icon
29
+ }
30
+ })
31
+
32
+ cy.get('.q-chip')
33
+ .get('.q-icon.q-chip__icon--left')
34
+ .should('have.text', `${ icon }`)
7
35
  })
8
36
  })
9
37
 
10
38
  describe('(prop): icon-right', () => {
11
- it.skip(' ', () => {
12
- //
39
+ it('should render an icon on the right', () => {
40
+ const icon = 'add'
41
+
42
+ mountQChip({
43
+ props: {
44
+ iconRight: icon
45
+ }
46
+ })
47
+
48
+ cy.get('.q-chip')
49
+ .get('.q-icon.q-chip__icon--right')
50
+ .should('have.text', `${ icon }`)
13
51
  })
14
52
  })
15
53
 
16
54
  describe('(prop): icon-remove', () => {
17
- it.skip(' ', () => {
18
- //
55
+ it('should render a custom remove icon', () => {
56
+ const icon = 'delete'
57
+
58
+ mountQChip({
59
+ props: {
60
+ removable: true,
61
+ iconRemove: icon
62
+ }
63
+ })
64
+
65
+ cy.get('.q-chip')
66
+ .get('.q-icon.q-chip__icon--remove')
67
+ .should('have.text', `${ icon }`)
19
68
  })
20
69
  })
21
70
 
22
71
  describe('(prop): icon-selected', () => {
23
- it.skip(' ', () => {
24
- //
72
+ it('should render a custom selected icon when one provided', () => {
73
+ const icon = 'done'
74
+
75
+ mountQChip({
76
+ props: {
77
+ selected: true,
78
+ iconSelected: icon
79
+ }
80
+ })
81
+
82
+ cy.get('.q-chip.q-chip--selected')
83
+ .get('.q-icon')
84
+ .should('have.text', `${ icon }`)
25
85
  })
26
86
  })
27
87
 
28
88
  describe('(prop): label', () => {
29
- it.skip(' ', () => {
30
- //
89
+ it('should render a label inside the chip', () => {
90
+ const label = 'Chip label'
91
+
92
+ mountQChip({
93
+ props: {
94
+ label
95
+ }
96
+ })
97
+
98
+ cy.get('.q-chip').get('.q-chip__content').should('have.text', label)
31
99
  })
32
100
  })
33
101
  })
34
102
 
35
103
  describe('Category: general', () => {
36
104
  describe('(prop): tabindex', () => {
37
- it.skip(' ', () => {
38
- //
105
+ it('should set the tabindex', () => {
106
+ const tabindex = 1
107
+
108
+ mountQChip({
109
+ props: {
110
+ clickable: true,
111
+ tabindex
112
+ }
113
+ })
114
+
115
+ cy.get('.q-chip').should('have.attr', 'tabindex', `${ tabindex }`)
39
116
  })
40
117
  })
41
118
  })
42
119
 
43
120
  describe('Category: model', () => {
44
121
  describe('(prop): model-value', () => {
45
- it.skip(' ', () => {
46
- //
122
+ it('should render when "modelValue" prop is true', () => {
123
+ mountQChip({
124
+ props: {
125
+ modelValue: true
126
+ }
127
+ })
128
+
129
+ cy.get('.q-chip').should('exist')
130
+ })
131
+
132
+ it('should not render when "modelValue" prop is false', () => {
133
+ mountQChip({
134
+ props: {
135
+ modelValue: false
136
+ }
137
+ })
138
+
139
+ cy.get('.q-chip').should('not.exist')
47
140
  })
48
141
  })
49
142
 
50
143
  describe('(prop): selected', () => {
51
- it.skip(' ', () => {
52
- //
144
+ it('should be selected when "selected" prop is true', () => {
145
+ mountQChip({
146
+ props: {
147
+ selected: true
148
+ }
149
+ })
150
+
151
+ cy.get('.q-chip.q-chip--selected').should('exist')
152
+ })
153
+
154
+ it('should not be selected when "selected" prop is false', () => {
155
+ mountQChip({
156
+ props: {
157
+ selected: false
158
+ }
159
+ })
160
+
161
+ cy.get('.q-chip').should('not.have.class', 'q-chip--selected')
53
162
  })
54
163
  })
55
164
  })
56
165
 
57
166
  describe('Category: state', () => {
58
167
  describe('(prop): clickable', () => {
59
- it.skip(' ', () => {
60
- //
168
+ it('should have hover effects and emit "click" event when "clickable" prop is true', () => {
169
+ const fn = cy.stub()
170
+
171
+ mountQChip({
172
+ props: {
173
+ clickable: true,
174
+ onClick: fn
175
+ }
176
+ })
177
+
178
+ cy.get('.q-chip')
179
+ .should('have.css', 'cursor', 'pointer')
180
+ .click()
181
+ .then(() => expect(fn).to.be.calledOnce)
61
182
  })
62
183
  })
63
184
 
64
185
  describe('(prop): removable', () => {
65
- it.skip(' ', () => {
66
- //
186
+ it('should display a remove icon emitting a "remove" event when clicked', () => {
187
+ const fn = cy.stub()
188
+
189
+ mountQChip({
190
+ props: {
191
+ removable: true,
192
+ onRemove: fn
193
+ }
194
+ })
195
+
196
+ cy.get('.q-chip')
197
+ .get('.q-icon.q-chip__icon--remove')
198
+ .click()
199
+ .then(() => expect(fn).to.be.calledOnce)
67
200
  })
68
201
  })
69
202
 
70
203
  describe('(prop): disable', () => {
71
- it.skip(' ', () => {
72
- //
204
+ it('should not have hover effect and not emit "click" event when "disable" prop is true', () => {
205
+ const fn = cy.stub()
206
+
207
+ mountQChip({
208
+ props: {
209
+ disable: true,
210
+ onClick: fn
211
+ }
212
+ })
213
+
214
+ cy.get('.q-chip')
215
+ .should('not.have.css', 'cursor', 'pointer')
216
+ .click()
217
+ .then(() => expect(fn).to.not.be.called)
73
218
  })
74
219
  })
75
220
  })
76
221
 
77
222
  describe('Category: style', () => {
78
223
  describe('(prop): dense', () => {
79
- it.skip(' ', () => {
80
- //
224
+ it('should have a dense style when "dense" prop is true', () => {
225
+ mountQChip({
226
+ props: {
227
+ dense: true
228
+ }
229
+ })
230
+
231
+ cy.get('.q-chip.q-chip--dense').should('exist')
81
232
  })
82
233
  })
83
234
 
84
235
  describe('(prop): size', () => {
85
- it.skip(' ', () => {
86
- //
236
+ it('should change QChip size based on a CSS unit value', () => {
237
+ const size = '50px'
238
+
239
+ mountQChip({
240
+ props: {
241
+ size
242
+ }
243
+ })
244
+
245
+ cy.get('.q-chip').should('have.css', 'font-size', size)
246
+ })
247
+
248
+ it(`should change QChip size based defined values: ${ chipSizeValues.join(', ') }`, () => {
249
+ mountQChip()
250
+
251
+ // loop over chipSizeValues
252
+ for (const key of chipSizeValues) {
253
+ cy.get('.q-chip')
254
+ .then(() => Cypress.vueWrapper.setProps({ size: key }))
255
+ .should('have.css', 'font-size', `${ defaultSizes[ key ] }px`)
256
+ }
87
257
  })
88
258
  })
89
259
 
90
260
  describe('(prop): dark', () => {
91
- it.skip(' ', () => {
92
- //
261
+ it('should have a dark style when "dark" prop is true', () => {
262
+ mountQChip({
263
+ props: {
264
+ dark: true
265
+ }
266
+ })
267
+
268
+ cy.get('.q-chip')
269
+ .should('have.class', 'q-dark')
270
+ .and('have.class', 'q-chip--dark')
93
271
  })
94
272
  })
95
273
 
96
274
  describe('(prop): color', () => {
97
- it.skip(' ', () => {
98
- //
275
+ it('should change color based on Quasar Color Palette', () => {
276
+ const color = 'red'
277
+
278
+ mountQChip({
279
+ props: {
280
+ color
281
+ }
282
+ })
283
+
284
+ cy.get('.q-chip').should('have.class', `bg-${ color }`)
99
285
  })
100
286
  })
101
287
 
102
288
  describe('(prop): text-color', () => {
103
- it.skip(' ', () => {
104
- //
289
+ it('should change text color based on Quasar Color Palette', () => {
290
+ const textColor = 'red'
291
+
292
+ mountQChip({
293
+ props: {
294
+ textColor
295
+ }
296
+ })
297
+
298
+ cy.get('.q-chip')
299
+ .should('have.class', 'q-chip--colored')
300
+ .and('have.class', `text-${ textColor }`)
105
301
  })
106
302
  })
107
303
 
108
304
  describe('(prop): square', () => {
109
- it.skip(' ', () => {
110
- //
305
+ it('should have a square style when "square" prop is true', () => {
306
+ mountQChip({
307
+ props: {
308
+ square: true
309
+ }
310
+ })
311
+
312
+ cy.get('.q-chip').should('have.class', 'q-chip--square')
111
313
  })
112
314
  })
113
315
 
114
316
  describe('(prop): outline', () => {
115
- it.skip(' ', () => {
116
- //
317
+ it('should have a outline style when "outline" prop is true', () => {
318
+ mountQChip({
319
+ props: {
320
+ outline: true
321
+ }
322
+ })
323
+
324
+ cy.get('.q-chip').should('have.class', 'q-chip--outline')
117
325
  })
118
326
  })
119
327
 
120
328
  describe('(prop): ripple', () => {
121
- it.skip(' ', () => {
122
- //
329
+ it('should have a ripple effect when "ripple" prop is true', () => {
330
+ mountQChip({
331
+ props: {
332
+ ripple: true
333
+ }
334
+ })
335
+
336
+ cy.get('.q-chip').click().get('.q-ripple').should('exist')
337
+ })
338
+
339
+ it('should not have a ripple effect when "ripple" prop is false', () => {
340
+ mountQChip({
341
+ props: {
342
+ ripple: false
343
+ }
344
+ })
345
+
346
+ cy.get('.q-chip').click().get('.q-ripple').should('not.exist')
123
347
  })
124
348
  })
125
349
  })
@@ -127,28 +351,117 @@ describe('Chip API', () => {
127
351
 
128
352
  describe('Slots', () => {
129
353
  describe('(slot): default', () => {
130
- it.skip(' ', () => {
131
- //
354
+ it('should display the default slot content', () => {
355
+ mountQChip({
356
+ props: {
357
+ label: undefined
358
+ },
359
+
360
+ slots: {
361
+ default: 'Default Slot Content'
362
+ }
363
+ })
364
+
365
+ cy.get('.q-chip').should('have.text', 'Default Slot Content')
132
366
  })
133
367
  })
134
368
  })
135
369
 
136
370
  describe('Events', () => {
137
371
  describe('(event): click', () => {
138
- it.skip(' ', () => {
139
- //
372
+ it('should emit "click" event when clicked and "clickable" prop is true', () => {
373
+ const fn = cy.stub()
374
+
375
+ mountQChip({
376
+ props: {
377
+ clickable: true,
378
+ onClick: fn
379
+ }
380
+ })
381
+
382
+ cy.get('.q-chip')
383
+ .click()
384
+ .then(() => expect(fn).to.be.calledOnce)
385
+ })
386
+
387
+ it('should not emit "click" event when "clickable" prop is false', () => {
388
+ const fn = cy.stub()
389
+
390
+ mountQChip({
391
+ props: {
392
+ clickable: false,
393
+ onClick: fn
394
+ }
395
+ })
396
+
397
+ cy.get('.q-chip')
398
+ .click()
399
+ .then(() => expect(fn).to.not.be.called)
140
400
  })
141
401
  })
142
402
 
143
403
  describe('(event): update:selected', () => {
144
- it.skip(' ', () => {
145
- //
404
+ it('should update selected value when called', () => {
405
+ const fn = cy.stub()
406
+
407
+ mountQChip({
408
+ props: {
409
+ selected: false,
410
+ 'onUpdate:selected': fn
411
+ }
412
+ })
413
+
414
+ cy.get('.q-chip')
415
+ .click()
416
+ .then(() => expect(fn).to.be.calledOnce)
417
+ })
418
+
419
+ it('should not emit update:selected event when "selected" prop is not set', () => {
420
+ const fn = cy.stub()
421
+
422
+ mountQChip({
423
+ props: {
424
+ selected: undefined,
425
+ 'onUpdate:selected': fn
426
+ }
427
+ })
428
+
429
+ cy.get('.q-chip')
430
+ .click()
431
+ .then(() => expect(fn).to.not.be.called)
146
432
  })
147
433
  })
148
434
 
149
435
  describe('(event): remove', () => {
150
- it.skip(' ', () => {
151
- //
436
+ it('should emit remove event when clicked and "removable" prop is true', () => {
437
+ const fn = cy.stub()
438
+
439
+ mountQChip({
440
+ props: {
441
+ removable: true,
442
+ onRemove: fn
443
+ }
444
+ })
445
+
446
+ cy.get('.q-chip')
447
+ .get('.q-icon.q-chip__icon--remove')
448
+ .click()
449
+ .then(() => expect(fn).to.be.calledOnce)
450
+ })
451
+
452
+ it('should not emit remove event when "removable" prop is false', () => {
453
+ const fn = cy.stub()
454
+
455
+ mountQChip({
456
+ props: {
457
+ removable: false,
458
+ onRemove: fn
459
+ }
460
+ })
461
+
462
+ cy.get('.q-chip')
463
+ .click()
464
+ .then(() => expect(fn).to.not.be.called)
152
465
  })
153
466
  })
154
467
  })
@@ -66,7 +66,7 @@ export default createComponent({
66
66
 
67
67
  const strokeWidth = computed(() => props.thickness / 2 * viewBox.value)
68
68
 
69
- function getCircle ({ thickness, offset, color, cls }) {
69
+ function getCircle ({ thickness, offset, color, cls, rounded }) {
70
70
  return h('circle', {
71
71
  class: 'q-circular-progress__' + cls + (color !== void 0 ? ` text-${ color }` : ''),
72
72
  style: circleStyle.value,
@@ -75,6 +75,7 @@ export default createComponent({
75
75
  'stroke-width': thickness,
76
76
  'stroke-dasharray': strokeDashArray,
77
77
  'stroke-dashoffset': offset,
78
+ 'stroke-linecap': rounded,
78
79
  cx: viewBox.value,
79
80
  cy: viewBox.value,
80
81
  r: radius
@@ -108,7 +109,8 @@ export default createComponent({
108
109
  cls: 'circle',
109
110
  thickness: strokeWidth.value,
110
111
  offset: strokeDashOffset.value,
111
- color: props.color
112
+ color: props.color,
113
+ rounded: props.rounded === true ? 'round' : void 0
112
114
  })
113
115
  )
114
116
 
@@ -53,6 +53,13 @@
53
53
  "category": "style"
54
54
  },
55
55
 
56
+ "rounded": {
57
+ "type": "Boolean",
58
+ "desc": "Rounding the arc of progress",
59
+ "category": "style",
60
+ "addedIn": "v2.8.4"
61
+ },
62
+
56
63
  "thickness": {
57
64
  "type": "Number",
58
65
  "default": 0.2,
@@ -18,6 +18,7 @@ export const useCircularCommonProps = {
18
18
  trackColor: String,
19
19
 
20
20
  fontSize: String,
21
+ rounded: Boolean,
21
22
 
22
23
  // ratio
23
24
  thickness: {
@@ -374,6 +374,7 @@ export default createComponent({
374
374
 
375
375
  function renderPortalContent () {
376
376
  return h('div', {
377
+ 'aria-modal': 'true',
377
378
  ...attrs,
378
379
  class: rootClasses.value
379
380
  }, [
@@ -37,6 +37,7 @@ export default createComponent({
37
37
 
38
38
  dense: Boolean,
39
39
 
40
+ toggleAriaLabel: String,
40
41
  expandIcon: String,
41
42
  expandedIcon: String,
42
43
  expandIconClass: [ Array, String, Object ],
@@ -47,6 +48,7 @@ export default createComponent({
47
48
 
48
49
  expandSeparator: Boolean,
49
50
  defaultOpened: Boolean,
51
+ hideExpandIcon: Boolean,
50
52
  expandIconToggle: Boolean,
51
53
  switchToggleSide: Boolean,
52
54
  denseToggle: Boolean,
@@ -73,8 +75,9 @@ export default createComponent({
73
75
  )
74
76
 
75
77
  const blurTargetRef = ref(null)
78
+ const targetUid = uid()
76
79
 
77
- const { hide, toggle } = useModelToggle({ showing })
80
+ const { show, hide, toggle } = useModelToggle({ showing })
78
81
 
79
82
  let uniqueId, exitGroup
80
83
 
@@ -124,6 +127,28 @@ export default createComponent({
124
127
  props.disable !== true && (hasLink.value === true || props.expandIconToggle === true)
125
128
  )
126
129
 
130
+ const headerSlotScope = computed(() => ({
131
+ expanded: showing.value === true,
132
+ detailsId: props.targetUid,
133
+ toggle,
134
+ show,
135
+ hide
136
+ }))
137
+
138
+ const toggleAriaAttrs = computed(() => {
139
+ const toggleAriaLabel = props.toggleAriaLabel !== void 0
140
+ ? props.toggleAriaLabel
141
+ : $q.lang.label[ showing.value === true ? 'collapse' : 'expand' ](props.label)
142
+
143
+ return {
144
+ role: 'button',
145
+ 'aria-expanded': showing.value === true ? 'true' : 'false',
146
+ 'aria-owns': targetUid,
147
+ 'aria-controls': targetUid,
148
+ 'aria-label': toggleAriaLabel
149
+ }
150
+ })
151
+
127
152
  watch(() => props.group, name => {
128
153
  exitGroup !== void 0 && exitGroup()
129
154
  name !== void 0 && enterGroup()
@@ -215,6 +240,7 @@ export default createComponent({
215
240
  if (activeToggleIcon.value === true) {
216
241
  Object.assign(data, {
217
242
  tabindex: 0,
243
+ ...toggleAriaAttrs.value,
218
244
  onClick: toggleIcon,
219
245
  onKeyup: toggleIconKeyboard
220
246
  })
@@ -235,7 +261,7 @@ export default createComponent({
235
261
  let child
236
262
 
237
263
  if (slots.header !== void 0) {
238
- child = [].concat(slots.header({ expanded: showing.value === true }))
264
+ child = [].concat(slots.header(headerSlotScope.value))
239
265
  }
240
266
  else {
241
267
  child = [
@@ -256,9 +282,11 @@ export default createComponent({
256
282
  )
257
283
  }
258
284
 
259
- props.disable !== true && child[ props.switchToggleSide === true ? 'unshift' : 'push' ](
260
- getToggleIcon()
261
- )
285
+ if (props.disable !== true && props.hideExpandIcon !== true) {
286
+ child[ props.switchToggleSide === true ? 'unshift' : 'push' ](
287
+ getToggleIcon()
288
+ )
289
+ }
262
290
 
263
291
  return child
264
292
  }
@@ -278,9 +306,9 @@ export default createComponent({
278
306
  data.clickable = true
279
307
  data.onClick = onHeaderClick
280
308
 
281
- hasLink.value === true && Object.assign(
309
+ Object.assign(
282
310
  data,
283
- linkProps.value
311
+ hasLink.value === true ? linkProps.value : toggleAriaAttrs.value
284
312
  )
285
313
  }
286
314
 
@@ -292,7 +320,8 @@ export default createComponent({
292
320
  h('div', {
293
321
  key: 'e-content',
294
322
  class: 'q-expansion-item__content relative-position',
295
- style: contentStyle.value
323
+ style: contentStyle.value,
324
+ id: targetUid
296
325
  }, hSlot(slots.default)),
297
326
  [ [
298
327
  vShow,