quasar 2.17.7 → 2.18.1

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 (291) hide show
  1. package/dist/api/QBtnDropdown.json +1 -1
  2. package/dist/api/QDialog.json +1 -1
  3. package/dist/api/QMenu.json +1 -1
  4. package/dist/api/QSelect.json +1 -1
  5. package/dist/api/QTable.json +1 -1
  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/mdi-v7.umd.prod.js +1 -1
  26. package/dist/icon-set/svg-bootstrap-icons.umd.prod.js +1 -1
  27. package/dist/icon-set/svg-eva-icons.umd.prod.js +1 -1
  28. package/dist/icon-set/svg-fontawesome-v5.umd.prod.js +1 -1
  29. package/dist/icon-set/svg-fontawesome-v6.umd.prod.js +1 -1
  30. package/dist/icon-set/svg-ionicons-v4.umd.prod.js +1 -1
  31. package/dist/icon-set/svg-ionicons-v5.umd.prod.js +1 -1
  32. package/dist/icon-set/svg-ionicons-v6.umd.prod.js +1 -1
  33. package/dist/icon-set/svg-line-awesome.umd.prod.js +1 -1
  34. package/dist/icon-set/svg-material-icons-outlined.umd.prod.js +1 -1
  35. package/dist/icon-set/svg-material-icons-round.umd.prod.js +1 -1
  36. package/dist/icon-set/svg-material-icons-sharp.umd.prod.js +1 -1
  37. package/dist/icon-set/svg-material-icons.umd.prod.js +1 -1
  38. package/dist/icon-set/svg-material-symbols-outlined.umd.prod.js +1 -1
  39. package/dist/icon-set/svg-material-symbols-rounded.umd.prod.js +1 -1
  40. package/dist/icon-set/svg-material-symbols-sharp.umd.prod.js +1 -1
  41. package/dist/icon-set/svg-mdi-v6.umd.prod.js +1 -1
  42. package/dist/icon-set/svg-mdi-v7.umd.prod.js +1 -1
  43. package/dist/icon-set/svg-themify.umd.prod.js +1 -1
  44. package/dist/icon-set/themify.umd.prod.js +1 -1
  45. package/dist/lang/ar-TN.umd.prod.js +2 -2
  46. package/dist/lang/ar.umd.prod.js +2 -2
  47. package/dist/lang/az-Latn.umd.prod.js +2 -2
  48. package/dist/lang/bg.umd.prod.js +2 -2
  49. package/dist/lang/bn.umd.prod.js +2 -2
  50. package/dist/lang/bs-BA.umd.prod.js +2 -2
  51. package/dist/lang/ca.umd.prod.js +2 -2
  52. package/dist/lang/cs.umd.prod.js +2 -2
  53. package/dist/lang/da.umd.prod.js +2 -2
  54. package/dist/lang/de-CH.umd.prod.js +2 -2
  55. package/dist/lang/de-DE.umd.prod.js +2 -2
  56. package/dist/lang/de.umd.prod.js +2 -2
  57. package/dist/lang/el.umd.prod.js +2 -2
  58. package/dist/lang/en-GB.umd.prod.js +2 -2
  59. package/dist/lang/en-US.umd.prod.js +2 -2
  60. package/dist/lang/eo.umd.prod.js +2 -2
  61. package/dist/lang/es.umd.prod.js +2 -2
  62. package/dist/lang/et.umd.prod.js +2 -2
  63. package/dist/lang/eu.umd.prod.js +2 -2
  64. package/dist/lang/fa-IR.umd.prod.js +2 -2
  65. package/dist/lang/fa.umd.prod.js +2 -2
  66. package/dist/lang/fi.umd.prod.js +2 -2
  67. package/dist/lang/fr.umd.prod.js +2 -2
  68. package/dist/lang/gn.umd.prod.js +2 -2
  69. package/dist/lang/he.umd.prod.js +2 -2
  70. package/dist/lang/hi.umd.prod.js +2 -2
  71. package/dist/lang/hr.umd.prod.js +2 -2
  72. package/dist/lang/hu.umd.prod.js +2 -2
  73. package/dist/lang/id.umd.prod.js +2 -2
  74. package/dist/lang/is.umd.prod.js +2 -2
  75. package/dist/lang/it.umd.prod.js +2 -2
  76. package/dist/lang/ja.umd.prod.js +2 -2
  77. package/dist/lang/kk.umd.prod.js +2 -2
  78. package/dist/lang/km.umd.prod.js +2 -2
  79. package/dist/lang/ko-KR.umd.prod.js +2 -2
  80. package/dist/lang/kur-CKB.umd.prod.js +2 -2
  81. package/dist/lang/lt.umd.prod.js +2 -2
  82. package/dist/lang/lu.umd.prod.js +2 -2
  83. package/dist/lang/lv.umd.prod.js +2 -2
  84. package/dist/lang/mk.umd.prod.js +2 -2
  85. package/dist/lang/ml.umd.prod.js +2 -2
  86. package/dist/lang/mm.umd.prod.js +2 -2
  87. package/dist/lang/ms-MY.umd.prod.js +2 -2
  88. package/dist/lang/ms.umd.prod.js +2 -2
  89. package/dist/lang/my.umd.prod.js +2 -2
  90. package/dist/lang/nb-NO.umd.prod.js +2 -2
  91. package/dist/lang/nl.umd.prod.js +2 -2
  92. package/dist/lang/pl.umd.prod.js +2 -2
  93. package/dist/lang/pt-BR.umd.prod.js +2 -2
  94. package/dist/lang/pt.umd.prod.js +2 -2
  95. package/dist/lang/ro.umd.prod.js +2 -2
  96. package/dist/lang/ru.umd.prod.js +2 -2
  97. package/dist/lang/sk.umd.prod.js +2 -2
  98. package/dist/lang/sl.umd.prod.js +2 -2
  99. package/dist/lang/sm.umd.prod.js +2 -2
  100. package/dist/lang/sr-CYR.umd.prod.js +2 -2
  101. package/dist/lang/sr.umd.prod.js +2 -2
  102. package/dist/lang/sv.umd.prod.js +2 -2
  103. package/dist/lang/ta.umd.prod.js +2 -2
  104. package/dist/lang/th.umd.prod.js +2 -2
  105. package/dist/lang/tl.umd.prod.js +2 -2
  106. package/dist/lang/tr.umd.prod.js +2 -2
  107. package/dist/lang/ug.umd.prod.js +2 -2
  108. package/dist/lang/uk.umd.prod.js +2 -2
  109. package/dist/lang/ur-PK.umd.prod.js +7 -0
  110. package/dist/lang/uz-Cyrl.umd.prod.js +2 -2
  111. package/dist/lang/uz-Latn.umd.prod.js +2 -2
  112. package/dist/lang/vi.umd.prod.js +2 -2
  113. package/dist/lang/zh-CN.umd.prod.js +2 -2
  114. package/dist/lang/zh-TW.umd.prod.js +2 -2
  115. package/dist/quasar.client.js +251 -175
  116. package/dist/quasar.css +8 -5
  117. package/dist/quasar.prod.css +1 -1
  118. package/dist/quasar.rtl.css +14 -6
  119. package/dist/quasar.rtl.prod.css +1 -1
  120. package/dist/quasar.sass +8 -5
  121. package/dist/quasar.server.prod.cjs +15 -15
  122. package/dist/quasar.server.prod.js +10 -10
  123. package/dist/quasar.umd.js +251 -175
  124. package/dist/quasar.umd.prod.js +17 -17
  125. package/dist/types/index.d.ts +52 -3
  126. package/dist/vetur/quasar-attributes.json +1 -1
  127. package/dist/vetur/quasar-tags.json +1 -1
  128. package/dist/web-types/web-types.json +1 -1
  129. package/lang/ar-TN.js +14 -1
  130. package/lang/ar.js +14 -1
  131. package/lang/az-Latn.js +14 -1
  132. package/lang/bg.js +14 -1
  133. package/lang/bn.js +14 -1
  134. package/lang/bs-BA.js +14 -1
  135. package/lang/ca.js +14 -1
  136. package/lang/cs.js +14 -1
  137. package/lang/da.js +14 -1
  138. package/lang/de-CH.js +14 -1
  139. package/lang/de-DE.js +14 -1
  140. package/lang/de.js +14 -1
  141. package/lang/el.js +14 -1
  142. package/lang/en-GB.js +14 -1
  143. package/lang/en-US.js +14 -1
  144. package/lang/eo.js +14 -1
  145. package/lang/es.js +14 -1
  146. package/lang/et.js +14 -1
  147. package/lang/eu.js +14 -1
  148. package/lang/fa-IR.js +14 -1
  149. package/lang/fa.js +14 -1
  150. package/lang/fi.js +14 -1
  151. package/lang/fr.js +14 -1
  152. package/lang/gn.js +14 -1
  153. package/lang/he.js +14 -1
  154. package/lang/hi.js +14 -1
  155. package/lang/hr.js +14 -1
  156. package/lang/hu.js +14 -1
  157. package/lang/id.js +14 -1
  158. package/lang/index.json +1 -1
  159. package/lang/is.js +14 -1
  160. package/lang/it.js +14 -1
  161. package/lang/ja.js +14 -1
  162. package/lang/kk.js +14 -1
  163. package/lang/km.js +14 -1
  164. package/lang/ko-KR.js +14 -1
  165. package/lang/kur-CKB.js +14 -1
  166. package/lang/lt.js +14 -1
  167. package/lang/lu.js +14 -1
  168. package/lang/lv.js +14 -1
  169. package/lang/mk.js +14 -1
  170. package/lang/ml.js +14 -1
  171. package/lang/mm.js +14 -1
  172. package/lang/ms-MY.js +14 -1
  173. package/lang/ms.js +14 -1
  174. package/lang/my.js +14 -1
  175. package/lang/nb-NO.js +14 -1
  176. package/lang/nl.js +14 -1
  177. package/lang/pl.js +14 -1
  178. package/lang/pt-BR.js +14 -1
  179. package/lang/pt.js +14 -1
  180. package/lang/ro.js +14 -1
  181. package/lang/ru.js +14 -1
  182. package/lang/sk.js +14 -1
  183. package/lang/sl.js +14 -1
  184. package/lang/sm.js +14 -1
  185. package/lang/sr-CYR.js +14 -1
  186. package/lang/sr.js +14 -1
  187. package/lang/sv.js +14 -1
  188. package/lang/ta.js +14 -1
  189. package/lang/th.js +14 -1
  190. package/lang/tl.js +14 -1
  191. package/lang/tr.js +14 -1
  192. package/lang/ug.js +8 -1
  193. package/lang/uk.js +14 -1
  194. package/lang/ur-PK.js +118 -0
  195. package/lang/uz-Cyrl.js +14 -1
  196. package/lang/uz-Latn.js +14 -1
  197. package/lang/vi.js +14 -1
  198. package/lang/zh-CN.js +14 -1
  199. package/lang/zh-TW.js +14 -1
  200. package/package.json +4 -4
  201. package/src/components/breadcrumbs/QBreadcrumbs.js +2 -2
  202. package/src/components/btn/QBtn.js +7 -8
  203. package/src/components/btn-dropdown/QBtnDropdown.js +10 -4
  204. package/src/components/btn-dropdown/QBtnDropdown.json +21 -0
  205. package/src/components/chip/QChip.sass +8 -4
  206. package/src/components/color/QColor.js +1 -1
  207. package/src/components/date/QDate.js +6 -1
  208. package/src/components/dialog/QDialog.js +2 -2
  209. package/src/components/dialog/QDialog.json +1 -1
  210. package/src/components/drawer/QDrawer.js +3 -5
  211. package/src/components/editor/QEditor.js +1 -1
  212. package/src/components/editor/editor-caret.js +1 -1
  213. package/src/components/editor/editor-utils.js +2 -2
  214. package/src/components/expansion-item/QExpansionItem.js +6 -3
  215. package/src/components/fab/QFab.js +2 -2
  216. package/src/components/form/QForm.js +2 -2
  217. package/src/components/form/QFormChildMixin.js +6 -4
  218. package/src/components/icon/QIcon.js +2 -2
  219. package/src/components/infinite-scroll/QInfiniteScroll.js +2 -4
  220. package/src/components/input/QInput.js +3 -3
  221. package/src/components/item/QItem.js +1 -1
  222. package/src/components/menu/QMenu.js +8 -5
  223. package/src/components/menu/QMenu.json +8 -1
  224. package/src/components/pagination/QPagination.js +8 -4
  225. package/src/components/parallax/QParallax.js +1 -1
  226. package/src/components/popup-edit/QPopupEdit.js +2 -2
  227. package/src/components/pull-to-refresh/QPullToRefresh.js +1 -1
  228. package/src/components/rating/QRating.sass +1 -1
  229. package/src/components/resize-observer/QResizeObserver.js +1 -1
  230. package/src/components/scroll-observer/QScrollObserver.js +2 -2
  231. package/src/components/select/QSelect.js +9 -6
  232. package/src/components/select/QSelect.json +1 -1
  233. package/src/components/slide-transition/QSlideTransition.js +2 -2
  234. package/src/components/stepper/StepHeader.js +1 -1
  235. package/src/components/table/QTable.js +77 -36
  236. package/src/components/table/QTable.json +98 -0
  237. package/src/components/table/QTr.js +4 -1
  238. package/src/components/table/table-sort.js +1 -1
  239. package/src/components/tabs/QTabs.js +2 -2
  240. package/src/components/tabs/use-tab.js +4 -4
  241. package/src/components/time/QTime.js +1 -1
  242. package/src/components/tree/QTree.js +2 -3
  243. package/src/components/virtual-scroll/use-virtual-scroll.js +3 -3
  244. package/src/composables/private.use-field/use-field.js +5 -5
  245. package/src/composables/private.use-file/use-file.js +6 -3
  246. package/src/composables/private.use-model-toggle/use-model-toggle.js +2 -2
  247. package/src/composables/private.use-refocus-target/use-refocus-target.js +6 -5
  248. package/src/composables/private.use-validate/use-validate.js +1 -1
  249. package/src/directives/intersection/Intersection.js +2 -2
  250. package/src/directives/morph/Morph.js +2 -2
  251. package/src/directives/mutation/Mutation.js +2 -2
  252. package/src/directives/touch-hold/TouchHold.js +2 -2
  253. package/src/directives/touch-pan/TouchPan.js +2 -2
  254. package/src/directives/touch-repeat/TouchRepeat.js +3 -3
  255. package/src/directives/touch-swipe/TouchSwipe.js +3 -3
  256. package/src/plugins/lang/Lang.test.js +28 -2
  257. package/src/plugins/loading/Loading.js +1 -1
  258. package/src/plugins/notify/Notify.js +1 -1
  259. package/src/plugins/private.body/Body.js +1 -1
  260. package/src/plugins/private.history/History.js +1 -1
  261. package/src/plugins/screen/Screen.js +1 -1
  262. package/src/utils/morph/morph.js +13 -10
  263. package/src/utils/open-url/open-url.js +3 -3
  264. package/src/utils/private.dialog/create-dialog.js +2 -2
  265. package/src/utils/private.portal/portal.js +1 -1
  266. package/src/components/date/__tests__/QDate.cy.js +0 -189
  267. package/src/components/date/__tests__/use-datetime.cy.js +0 -83
  268. package/src/components/editor/__tests__/QEditor.cy.js +0 -195
  269. package/src/components/field/__tests__/QField.cy.js +0 -156
  270. package/src/components/input/__tests__/QInput.cy.js +0 -786
  271. package/src/components/input/__tests__/use-mask.cy.js +0 -124
  272. package/src/components/menu/__tests__/QMenu.cy.js +0 -634
  273. package/src/components/menu/__tests__/WrapperOne.vue +0 -51
  274. package/src/components/menu/__tests__/WrapperTwo.vue +0 -38
  275. package/src/components/select/__tests__/QSelect.cy.js +0 -2018
  276. package/src/components/table/__tests__/QTable.cy.js +0 -635
  277. package/src/components/table/__tests__/QTd.cy.js +0 -35
  278. package/src/components/table/__tests__/QTh.cy.js +0 -27
  279. package/src/components/table/__tests__/QTr.cy.js +0 -27
  280. package/src/components/tabs/__tests__/QTab.cy.js +0 -79
  281. package/src/components/tabs/__tests__/QTabs.cy.js +0 -147
  282. package/src/components/uploader/__tests__/QUploader.cy.js +0 -191
  283. package/src/composables/__tests__/FieldWrapper.vue +0 -54
  284. package/src/composables/__tests__/use-anchor.cy.js +0 -98
  285. package/src/composables/__tests__/use-field.cy.js +0 -547
  286. package/src/composables/__tests__/use-file.cy.js +0 -69
  287. package/src/composables/__tests__/use-fullscreen.cy.js +0 -37
  288. package/src/composables/__tests__/use-model-toggle.cy.js +0 -350
  289. package/src/composables/__tests__/use-portal.cy.js +0 -4
  290. package/src/composables/__tests__/use-router-link.cy.js +0 -55
  291. package/src/composables/__tests__/use-validate.cy.js +0 -257
@@ -114,7 +114,7 @@ export default createComponent({
114
114
  if (props.onSubmit !== void 0) {
115
115
  emit('submit', evt)
116
116
  }
117
- else if (evt !== void 0 && evt.target !== void 0 && typeof evt.target.submit === 'function') {
117
+ else if (evt?.target !== void 0 && typeof evt.target.submit === 'function') {
118
118
  evt.target.submit()
119
119
  }
120
120
  }
@@ -143,7 +143,7 @@ export default createComponent({
143
143
  || rootRef.value.querySelector('[autofocus], [data-autofocus]')
144
144
  || Array.prototype.find.call(rootRef.value.querySelectorAll('[tabindex]'), el => el.tabIndex !== -1)
145
145
 
146
- target !== null && target !== void 0 && target.focus({ preventScroll: true })
146
+ target?.focus({ preventScroll: true })
147
147
  })
148
148
  }
149
149
 
@@ -30,13 +30,15 @@ export default {
30
30
 
31
31
  mounted () {
32
32
  // register to parent QForm
33
- const $form = this.$.provides[ formKey ]
34
- $form !== void 0 && this.disable !== true && $form.bindComponent(this)
33
+ if (this.disable !== true) {
34
+ this.$.provides[ formKey ]?.bindComponent(this)
35
+ }
35
36
  },
36
37
 
37
38
  beforeUnmount () {
38
39
  // un-register from parent QForm
39
- const $form = this.$.provides[ formKey ]
40
- $form !== void 0 && this.disable !== true && $form.unbindComponent(this)
40
+ if (this.disable !== true) {
41
+ this.$.provides[ formKey ]?.unbindComponent(this)
42
+ }
41
43
  }
42
44
  }
@@ -20,7 +20,8 @@ const libMap = {
20
20
  'ion-logo': ionFn,
21
21
  'iconfont ': sameFn,
22
22
  'ti-': i => `themify-icon ${ i }`,
23
- 'bi-': i => `bootstrap-icons ${ i }`
23
+ 'bi-': i => `bootstrap-icons ${ i }`,
24
+ 'i-': sameFn // UnoCSS pure icons
24
25
  }
25
26
 
26
27
  const matMap = {
@@ -186,7 +187,6 @@ export default createComponent({
186
187
  class: classes.value,
187
188
  style: sizeStyle.value,
188
189
  'aria-hidden': 'true',
189
- role: 'presentation'
190
190
  }
191
191
 
192
192
  if (type.value.none === true) {
@@ -126,9 +126,7 @@ export default createComponent({
126
126
  isWorking.value = false
127
127
  isFetching.value = false
128
128
  localScrollTarget.removeEventListener('scroll', poll, passive)
129
- if (poll !== void 0 && poll.cancel !== void 0) {
130
- poll.cancel()
131
- }
129
+ poll?.cancel?.()
132
130
  }
133
131
  }
134
132
 
@@ -240,7 +238,7 @@ export default createComponent({
240
238
  // expose public methods
241
239
  const vm = getCurrentInstance()
242
240
  Object.assign(vm.proxy, {
243
- poll: () => { poll !== void 0 && poll() },
241
+ poll: () => { poll?.() },
244
242
  trigger, stop, reset, resume, setIndex, updateScrollTarget
245
243
  })
246
244
 
@@ -203,7 +203,7 @@ export default createComponent({
203
203
  }
204
204
 
205
205
  function select () {
206
- inputRef.value !== null && inputRef.value.select()
206
+ inputRef.value?.select()
207
207
  }
208
208
 
209
209
  function onPaste (e) {
@@ -340,7 +340,7 @@ export default createComponent({
340
340
  emitTimer = null
341
341
  }
342
342
 
343
- emitValueFn !== void 0 && emitValueFn()
343
+ emitValueFn?.()
344
344
 
345
345
  emit('change', e.target.value)
346
346
  }
@@ -353,7 +353,7 @@ export default createComponent({
353
353
  emitTimer = null
354
354
  }
355
355
 
356
- emitValueFn !== void 0 && emitValueFn()
356
+ emitValueFn?.()
357
357
 
358
358
  typedNumber = false
359
359
  stopValueWatcher = false
@@ -92,7 +92,7 @@ export default createComponent({
92
92
 
93
93
  function onClick (e) {
94
94
  if (isClickable.value === true) {
95
- if (blurTargetRef.value !== null) {
95
+ if (blurTargetRef.value !== null && e.qAvoidFocus !== true) {
96
96
  if (e.qKeyEvent !== true && document.activeElement === rootRef.value) {
97
97
  blurTargetRef.value.focus()
98
98
  }
@@ -38,7 +38,7 @@ export default createComponent({
38
38
  persistent: Boolean,
39
39
  autoClose: Boolean,
40
40
  separateClosePopup: Boolean,
41
-
41
+ noEscDismiss: Boolean,
42
42
  noRouteDismiss: Boolean,
43
43
  noRefocus: Boolean,
44
44
  noFocus: Boolean,
@@ -177,7 +177,7 @@ export default createComponent({
177
177
  addFocusFn(() => {
178
178
  let node = innerRef.value
179
179
 
180
- if (node && node.contains(document.activeElement) !== true) {
180
+ if (node && (node.contains(document.activeElement) !== true)) {
181
181
  node = node.querySelector('[autofocus][tabindex], [data-autofocus][tabindex]')
182
182
  || node.querySelector('[autofocus] [tabindex], [data-autofocus] [tabindex]')
183
183
  || node.querySelector('[autofocus], [data-autofocus]')
@@ -256,10 +256,11 @@ export default createComponent({
256
256
  || evt.qClickOutside !== true
257
257
  )
258
258
  ) {
259
- ((evt && evt.type.indexOf('key') === 0
259
+ ((evt?.type.indexOf('key') === 0
260
260
  ? refocusTarget.closest('[tabindex]:not([tabindex^="-"])')
261
261
  : void 0
262
262
  ) || refocusTarget).focus()
263
+
263
264
  refocusTarget = null
264
265
  }
265
266
 
@@ -321,8 +322,10 @@ export default createComponent({
321
322
  }
322
323
 
323
324
  function onEscapeKey (evt) {
324
- emit('escapeKey')
325
- hide(evt)
325
+ if (props.noEscDismiss !== true) {
326
+ emit('escapeKey')
327
+ hide(evt)
328
+ }
326
329
  }
327
330
 
328
331
  function updatePosition () {
@@ -67,6 +67,13 @@
67
67
  "category": "behavior"
68
68
  },
69
69
 
70
+ "no-esc-dismiss": {
71
+ "type": "Boolean",
72
+ "desc": "User cannot dismiss the popup by hitting ESC key; No need to set it if 'persistent' prop is also set",
73
+ "category": "behavior",
74
+ "addedIn": "v2.18"
75
+ },
76
+
70
77
  "no-route-dismiss": {
71
78
  "type": "Boolean",
72
79
  "desc": "Changing route app won't dismiss the popup; No need to set it if 'persistent' prop is also set",
@@ -128,7 +135,7 @@
128
135
 
129
136
  "events": {
130
137
  "escape-key": {
131
- "desc": "Emitted when ESC key is pressed; Does not get emitted if Menu is 'persistent'"
138
+ "desc": "Emitted when ESC key is pressed; Does not get emitted if Menu is 'persistent' or it has 'no-esc-dismiss' set"
132
139
  },
133
140
 
134
141
  "click": { "internal": true }
@@ -317,7 +317,8 @@ export default createComponent({
317
317
  getBtn({
318
318
  key: 'bls',
319
319
  disable: props.disable || props.modelValue <= minProp.value,
320
- icon: icons.value[ 0 ]
320
+ icon: icons.value[ 0 ],
321
+ 'aria-label': $q.lang.pagination.first
321
322
  }, minProp.value)
322
323
  )
323
324
 
@@ -325,7 +326,8 @@ export default createComponent({
325
326
  getBtn({
326
327
  key: 'ble',
327
328
  disable: props.disable || props.modelValue >= maxProp.value,
328
- icon: icons.value[ 3 ]
329
+ icon: icons.value[ 3 ],
330
+ 'aria-label': $q.lang.pagination.last
329
331
  }, maxProp.value)
330
332
  )
331
333
  }
@@ -335,7 +337,8 @@ export default createComponent({
335
337
  getBtn({
336
338
  key: 'bdp',
337
339
  disable: props.disable || props.modelValue <= minProp.value,
338
- icon: icons.value[ 1 ]
340
+ icon: icons.value[ 1 ],
341
+ 'aria-label': $q.lang.pagination.prev
339
342
  }, props.modelValue - 1)
340
343
  )
341
344
 
@@ -343,7 +346,8 @@ export default createComponent({
343
346
  getBtn({
344
347
  key: 'bdn',
345
348
  disable: props.disable || props.modelValue >= maxProp.value,
346
- icon: icons.value[ 2 ]
349
+ icon: icons.value[ 2 ],
350
+ 'aria-label': $q.lang.pagination.next
347
351
  }, props.modelValue + 1)
348
352
  )
349
353
  }
@@ -134,7 +134,7 @@ export default createComponent({
134
134
 
135
135
  onBeforeUnmount(() => {
136
136
  stop()
137
- observer !== void 0 && observer.disconnect()
137
+ observer?.disconnect()
138
138
  mediaEl.onload = mediaEl.onloadstart = mediaEl.loadedmetadata = null
139
139
  })
140
140
 
@@ -163,8 +163,8 @@ export default createComponent({
163
163
  Object.assign(proxy, {
164
164
  set,
165
165
  cancel,
166
- show (e) { menuRef.value !== null && menuRef.value.show(e) },
167
- hide (e) { menuRef.value !== null && menuRef.value.hide(e) },
166
+ show (e) { menuRef.value?.show(e) },
167
+ hide (e) { menuRef.value?.hide(e) },
168
168
  updatePosition
169
169
  })
170
170
 
@@ -149,7 +149,7 @@ export default createComponent({
149
149
  timer = setTimeout(() => {
150
150
  timer = null
151
151
  animating.value = false
152
- done && done()
152
+ done?.()
153
153
  }, 300)
154
154
  }
155
155
 
@@ -14,7 +14,7 @@
14
14
  text-shadow: $rating-shadow
15
15
  position: relative
16
16
  opacity: .4
17
- transition: transform .2s ease-in, opacity .2s ease-in
17
+ transition: transform .2s ease-in, opacity .2s ease-in, color .2s ease-in
18
18
 
19
19
  &--hovered
20
20
  transform: scale(1.3)
@@ -117,7 +117,7 @@ export default createComponent({
117
117
  function onObjLoad () {
118
118
  cleanup()
119
119
 
120
- if (targetEl && targetEl.contentDocument) {
120
+ if (targetEl?.contentDocument) {
121
121
  curDocView = targetEl.contentDocument.defaultView
122
122
  curDocView.addEventListener('resize', trigger, listenOpts.passive)
123
123
  emitEvent()
@@ -53,7 +53,7 @@ export default createComponent({
53
53
  })
54
54
 
55
55
  function emitEvent () {
56
- clearTimer !== null && clearTimer()
56
+ clearTimer?.()
57
57
 
58
58
  const top = Math.max(0, getVerticalScrollPosition(localScrollTarget))
59
59
  const left = getHorizontalScrollPosition(localScrollTarget)
@@ -123,7 +123,7 @@ export default createComponent({
123
123
  })
124
124
 
125
125
  onBeforeUnmount(() => {
126
- clearTimer !== null && clearTimer()
126
+ clearTimer?.()
127
127
  unconfigureScrollTarget()
128
128
  })
129
129
 
@@ -273,7 +273,7 @@ export default createComponent({
273
273
  const needsHtmlFn = computed(() => (
274
274
  props.optionsHtml === true
275
275
  ? () => true
276
- : opt => opt !== void 0 && opt !== null && opt.html === true
276
+ : opt => opt?.html === true
277
277
  ))
278
278
 
279
279
  const valueAsHtml = computed(() => (
@@ -533,7 +533,7 @@ export default createComponent({
533
533
  hidePopup()
534
534
  }
535
535
 
536
- targetRef.value !== null && targetRef.value.focus()
536
+ targetRef.value?.focus()
537
537
 
538
538
  if (
539
539
  innerValue.value.length === 0
@@ -545,7 +545,9 @@ export default createComponent({
545
545
  return
546
546
  }
547
547
 
548
- (hasDialog !== true || dialogFieldFocused.value === true) && state.focus()
548
+ if (hasDialog !== true || dialogFieldFocused.value === true) {
549
+ state.focus()
550
+ }
549
551
 
550
552
  selectInputText()
551
553
 
@@ -894,7 +896,7 @@ export default createComponent({
894
896
  fn(val, mode === 'add-unique')
895
897
 
896
898
  if (props.multiple !== true) {
897
- targetRef.value !== null && targetRef.value.focus()
899
+ targetRef.value?.focus()
898
900
  hidePopup()
899
901
  }
900
902
  }
@@ -960,6 +962,7 @@ export default createComponent({
960
962
 
961
963
  return [
962
964
  h('span', {
965
+ class: 'ellipsis',
963
966
  [ valueAsHtml.value === true ? 'innerHTML' : 'textContent' ]: ariaCurrentValue.value
964
967
  })
965
968
  ]
@@ -1214,7 +1217,7 @@ export default createComponent({
1214
1217
 
1215
1218
  function onDialogFieldFocus (e) {
1216
1219
  stop(e)
1217
- targetRef.value !== null && targetRef.value.focus()
1220
+ targetRef.value?.focus()
1218
1221
  dialogFieldFocused.value = true
1219
1222
  window.scrollTo(window.pageXOffset || window.scrollX || document.body.scrollLeft || 0, 0)
1220
1223
  }
@@ -1511,7 +1514,7 @@ export default createComponent({
1511
1514
 
1512
1515
  if (hasDialog !== true && menu.value === true) {
1513
1516
  closeMenu()
1514
- targetRef.value !== null && targetRef.value.focus()
1517
+ targetRef.value?.focus()
1515
1518
  return
1516
1519
  }
1517
1520
 
@@ -260,7 +260,7 @@
260
260
 
261
261
  "fill-input": {
262
262
  "type": "Boolean",
263
- "desc": "Fills the input with current value; Useful along with 'hide-selected'; Does NOT works along with 'multiple' selection",
263
+ "desc": "Fills the input with current value; Useful along with 'hide-selected'; Does NOT work along with 'multiple' selection",
264
264
  "category": "behavior"
265
265
  },
266
266
 
@@ -20,7 +20,7 @@ export default createComponent({
20
20
  let timer = null, timerFallback = null, animListener, lastEvent
21
21
 
22
22
  function cleanup () {
23
- doneFn && doneFn()
23
+ doneFn?.()
24
24
  doneFn = null
25
25
  animating = false
26
26
 
@@ -34,7 +34,7 @@ export default createComponent({
34
34
  timerFallback = null
35
35
  }
36
36
 
37
- element !== void 0 && element.removeEventListener('transitionend', animListener)
37
+ element?.removeEventListener('transitionend', animListener)
38
38
  animListener = null
39
39
  }
40
40
 
@@ -119,7 +119,7 @@ export default createComponent({
119
119
  ))
120
120
 
121
121
  function onActivate () {
122
- blurRef.value !== null && blurRef.value.focus()
122
+ blurRef.value?.focus()
123
123
  isActive.value === false && props.goToPanel(props.step.name)
124
124
  }
125
125
 
@@ -91,10 +91,14 @@ export default createComponent({
91
91
  tableClass: [ String, Array, Object ],
92
92
  tableHeaderStyle: [ String, Array, Object ],
93
93
  tableHeaderClass: [ String, Array, Object ],
94
+ tableRowStyleFn: Function,
95
+ tableRowClassFn: Function,
94
96
  cardContainerClass: [ String, Array, Object ],
95
97
  cardContainerStyle: [ String, Array, Object ],
96
98
  cardStyle: [ String, Array, Object ],
97
99
  cardClass: [ String, Array, Object ],
100
+ cardStyleFn: Function,
101
+ cardClassFn: Function,
98
102
 
99
103
  hideBottom: Boolean,
100
104
  hideSelectedBanner: Boolean,
@@ -148,7 +152,7 @@ export default createComponent({
148
152
  + (props.bordered === true ? ' q-table--bordered' : '')
149
153
  )
150
154
 
151
- const __containerClass = computed(() =>
155
+ const containerClass = computed(() =>
152
156
  `q-table__container q-table--${ props.separator }-separator column no-wrap`
153
157
  + (props.grid === true ? ' q-table--grid' : cardDefaultClass.value)
154
158
  + (isDark.value === true ? ' q-table--dark' : '')
@@ -157,13 +161,13 @@ export default createComponent({
157
161
  + (inFullscreen.value === true ? ' fullscreen scroll' : '')
158
162
  )
159
163
 
160
- const containerClass = computed(() =>
161
- __containerClass.value + (props.loading === true ? ' q-table--loading' : '')
164
+ const rootContainerClass = computed(() =>
165
+ containerClass.value + (props.loading === true ? ' q-table--loading' : '')
162
166
  )
163
167
 
164
168
  watch(
165
- () => props.tableStyle + props.tableClass + props.tableHeaderStyle + props.tableHeaderClass + __containerClass.value,
166
- () => { hasVirtScroll.value === true && virtScrollRef.value !== null && virtScrollRef.value.reset() }
169
+ () => props.tableStyle + props.tableClass + props.tableHeaderStyle + props.tableHeaderClass + containerClass.value,
170
+ () => { hasVirtScroll.value === true && virtScrollRef.value?.reset() }
167
171
  )
168
172
 
169
173
  const {
@@ -382,13 +386,26 @@ export default createComponent({
382
386
  selected = isRowSelected(key)
383
387
 
384
388
  if (bodySlot !== void 0) {
389
+ const cfg = {
390
+ key,
391
+ row,
392
+ pageIndex,
393
+ __trClass: selected ? 'selected' : ''
394
+ }
395
+
396
+ if (props.tableRowStyleFn !== void 0) {
397
+ cfg.__trStyle = props.tableRowStyleFn(row)
398
+ }
399
+
400
+ if (props.tableRowClassFn !== void 0) {
401
+ const cls = props.tableRowClassFn(row)
402
+ if (cls) {
403
+ cfg.__trClass = `${ cls } ${ cfg.__trClass }`
404
+ }
405
+ }
406
+
385
407
  return bodySlot(
386
- getBodyScope({
387
- key,
388
- row,
389
- pageIndex,
390
- __trClass: selected ? 'selected' : ''
391
- })
408
+ getBodyScope(cfg)
392
409
  )
393
410
  }
394
411
 
@@ -451,6 +468,17 @@ export default createComponent({
451
468
  }
452
469
  }
453
470
 
471
+ if (props.tableRowStyleFn !== void 0) {
472
+ data.style = props.tableRowStyleFn(row)
473
+ }
474
+
475
+ if (props.tableRowClassFn !== void 0) {
476
+ const cls = props.tableRowClassFn(row)
477
+ if (cls) {
478
+ data.class[ cls ] = true
479
+ }
480
+ }
481
+
454
482
  return h('tr', data, child)
455
483
  }
456
484
 
@@ -792,30 +820,28 @@ export default createComponent({
792
820
  h('div', { class: 'q-table__separator col' })
793
821
  )
794
822
 
795
- if (hasOpts === true) {
796
- child.push(
797
- h('div', { class: 'q-table__control' }, [
798
- h('span', { class: 'q-table__bottom-item' }, [
799
- props.rowsPerPageLabel || $q.lang.table.recordsPerPage
800
- ]),
801
- h(QSelect, {
802
- class: 'q-table__select inline q-table__bottom-item',
803
- color: props.color,
804
- modelValue: rowsPerPage,
805
- options: computedRowsPerPageOptions.value,
806
- displayValue: rowsPerPage === 0
807
- ? $q.lang.table.allRows
808
- : rowsPerPage,
809
- dark: isDark.value,
810
- borderless: true,
811
- dense: true,
812
- optionsDense: true,
813
- optionsCover: true,
814
- 'onUpdate:modelValue': onPagSelection
815
- })
816
- ])
817
- )
818
- }
823
+ hasOpts === true && child.push(
824
+ h('div', { class: 'q-table__control' }, [
825
+ h('span', { class: 'q-table__bottom-item' }, [
826
+ props.rowsPerPageLabel || $q.lang.table.recordsPerPage
827
+ ]),
828
+ h(QSelect, {
829
+ class: 'q-table__select inline q-table__bottom-item',
830
+ color: props.color,
831
+ modelValue: rowsPerPage,
832
+ options: computedRowsPerPageOptions.value,
833
+ displayValue: rowsPerPage === 0
834
+ ? $q.lang.table.allRows
835
+ : rowsPerPage,
836
+ dark: isDark.value,
837
+ borderless: true,
838
+ dense: true,
839
+ optionsDense: true,
840
+ optionsCover: true,
841
+ 'onUpdate:modelValue': onPagSelection
842
+ })
843
+ ])
844
+ )
819
845
 
820
846
  if (paginationSlot !== void 0) {
821
847
  control = paginationSlot(marginalsScope.value)
@@ -847,6 +873,7 @@ export default createComponent({
847
873
  ...btnProps,
848
874
  icon: navIcon.value[ 0 ],
849
875
  disable: isFirstPage.value,
876
+ ariaLabel: $q.lang.pagination.first,
850
877
  onClick: firstPage
851
878
  })
852
879
  )
@@ -857,6 +884,7 @@ export default createComponent({
857
884
  ...btnProps,
858
885
  icon: navIcon.value[ 1 ],
859
886
  disable: isFirstPage.value,
887
+ ariaLabel: $q.lang.pagination.prev,
860
888
  onClick: prevPage
861
889
  }),
862
890
 
@@ -865,6 +893,7 @@ export default createComponent({
865
893
  ...btnProps,
866
894
  icon: navIcon.value[ 2 ],
867
895
  disable: isLastPage.value,
896
+ ariaLabel: $q.lang.pagination.next,
868
897
  onClick: nextPage
869
898
  })
870
899
  )
@@ -875,6 +904,7 @@ export default createComponent({
875
904
  ...btnProps,
876
905
  icon: navIcon.value[ 3 ],
877
906
  disable: isLastPage.value,
907
+ ariaLabel: $q.lang.pagination.last,
878
908
  onClick: lastPage
879
909
  })
880
910
  )
@@ -945,6 +975,17 @@ export default createComponent({
945
975
  style: props.cardStyle
946
976
  }
947
977
 
978
+ if (props.cardStyleFn !== void 0) {
979
+ data.style = [ data.style, props.cardStyleFn(scope.row) ]
980
+ }
981
+
982
+ if (props.cardClassFn !== void 0) {
983
+ const cls = props.cardClassFn(scope.row)
984
+ if (cls) {
985
+ data.class[ 0 ] += ` ${ cls }`
986
+ }
987
+ }
988
+
948
989
  if (
949
990
  props.onRowClick !== void 0
950
991
  || props.onRowDblclick !== void 0
@@ -1020,7 +1061,7 @@ export default createComponent({
1020
1061
 
1021
1062
  return () => {
1022
1063
  const child = [ getTopDiv() ]
1023
- const data = { ref: rootRef, class: containerClass.value }
1064
+ const data = { ref: rootRef, class: rootContainerClass.value }
1024
1065
 
1025
1066
  if (props.grid === true) {
1026
1067
  child.push(getGridHeader())