quasar 2.17.7 → 2.18.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 (289) 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 +1 -1
  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 +237 -174
  116. package/dist/quasar.css +1 -1
  117. package/dist/quasar.prod.css +1 -1
  118. package/dist/quasar.rtl.css +1 -1
  119. package/dist/quasar.rtl.prod.css +1 -1
  120. package/dist/quasar.sass +2 -2
  121. package/dist/quasar.server.prod.cjs +15 -15
  122. package/dist/quasar.server.prod.js +8 -8
  123. package/dist/quasar.umd.js +237 -174
  124. package/dist/quasar.umd.prod.js +15 -15
  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 +6 -0
  130. package/lang/ar.js +6 -0
  131. package/lang/az-Latn.js +6 -0
  132. package/lang/bg.js +6 -0
  133. package/lang/bn.js +6 -0
  134. package/lang/bs-BA.js +6 -0
  135. package/lang/ca.js +6 -0
  136. package/lang/cs.js +6 -0
  137. package/lang/da.js +6 -0
  138. package/lang/de-CH.js +6 -0
  139. package/lang/de-DE.js +6 -0
  140. package/lang/de.js +6 -0
  141. package/lang/el.js +6 -0
  142. package/lang/en-GB.js +6 -0
  143. package/lang/en-US.js +6 -0
  144. package/lang/eo.js +6 -0
  145. package/lang/es.js +6 -0
  146. package/lang/et.js +6 -0
  147. package/lang/eu.js +6 -0
  148. package/lang/fa-IR.js +6 -0
  149. package/lang/fa.js +6 -0
  150. package/lang/fi.js +6 -0
  151. package/lang/fr.js +6 -0
  152. package/lang/gn.js +6 -0
  153. package/lang/he.js +6 -0
  154. package/lang/hi.js +6 -0
  155. package/lang/hr.js +6 -0
  156. package/lang/hu.js +6 -0
  157. package/lang/id.js +6 -0
  158. package/lang/index.json +1 -1
  159. package/lang/is.js +6 -0
  160. package/lang/it.js +6 -0
  161. package/lang/ja.js +6 -0
  162. package/lang/kk.js +6 -0
  163. package/lang/km.js +6 -0
  164. package/lang/ko-KR.js +6 -0
  165. package/lang/kur-CKB.js +6 -0
  166. package/lang/lt.js +6 -0
  167. package/lang/lu.js +6 -0
  168. package/lang/lv.js +6 -0
  169. package/lang/mk.js +6 -0
  170. package/lang/ml.js +6 -0
  171. package/lang/mm.js +6 -0
  172. package/lang/ms-MY.js +6 -0
  173. package/lang/ms.js +6 -0
  174. package/lang/my.js +6 -0
  175. package/lang/nb-NO.js +6 -0
  176. package/lang/nl.js +6 -0
  177. package/lang/pl.js +6 -0
  178. package/lang/pt-BR.js +6 -0
  179. package/lang/pt.js +6 -0
  180. package/lang/ro.js +6 -0
  181. package/lang/ru.js +6 -0
  182. package/lang/sk.js +6 -0
  183. package/lang/sl.js +6 -0
  184. package/lang/sm.js +6 -0
  185. package/lang/sr-CYR.js +6 -0
  186. package/lang/sr.js +6 -0
  187. package/lang/sv.js +6 -0
  188. package/lang/ta.js +6 -0
  189. package/lang/th.js +6 -0
  190. package/lang/tl.js +6 -0
  191. package/lang/tr.js +6 -0
  192. package/lang/uk.js +6 -0
  193. package/lang/ur-PK.js +111 -0
  194. package/lang/uz-Cyrl.js +6 -0
  195. package/lang/uz-Latn.js +6 -0
  196. package/lang/vi.js +6 -0
  197. package/lang/zh-CN.js +6 -0
  198. package/lang/zh-TW.js +6 -0
  199. package/package.json +3 -3
  200. package/src/components/breadcrumbs/QBreadcrumbs.js +2 -2
  201. package/src/components/btn/QBtn.js +7 -8
  202. package/src/components/btn-dropdown/QBtnDropdown.js +10 -4
  203. package/src/components/btn-dropdown/QBtnDropdown.json +21 -0
  204. package/src/components/color/QColor.js +1 -1
  205. package/src/components/date/QDate.js +1 -1
  206. package/src/components/dialog/QDialog.js +2 -2
  207. package/src/components/dialog/QDialog.json +1 -1
  208. package/src/components/drawer/QDrawer.js +3 -5
  209. package/src/components/editor/QEditor.js +1 -1
  210. package/src/components/editor/editor-caret.js +1 -1
  211. package/src/components/editor/editor-utils.js +2 -2
  212. package/src/components/expansion-item/QExpansionItem.js +6 -3
  213. package/src/components/fab/QFab.js +2 -2
  214. package/src/components/form/QForm.js +2 -2
  215. package/src/components/form/QFormChildMixin.js +6 -4
  216. package/src/components/icon/QIcon.js +2 -2
  217. package/src/components/infinite-scroll/QInfiniteScroll.js +2 -4
  218. package/src/components/input/QInput.js +3 -3
  219. package/src/components/item/QItem.js +1 -1
  220. package/src/components/menu/QMenu.js +8 -5
  221. package/src/components/menu/QMenu.json +8 -1
  222. package/src/components/pagination/QPagination.js +8 -4
  223. package/src/components/parallax/QParallax.js +1 -1
  224. package/src/components/popup-edit/QPopupEdit.js +2 -2
  225. package/src/components/pull-to-refresh/QPullToRefresh.js +1 -1
  226. package/src/components/rating/QRating.sass +1 -1
  227. package/src/components/resize-observer/QResizeObserver.js +1 -1
  228. package/src/components/scroll-observer/QScrollObserver.js +2 -2
  229. package/src/components/select/QSelect.js +8 -6
  230. package/src/components/select/QSelect.json +1 -1
  231. package/src/components/slide-transition/QSlideTransition.js +2 -2
  232. package/src/components/stepper/StepHeader.js +1 -1
  233. package/src/components/table/QTable.js +77 -36
  234. package/src/components/table/QTable.json +98 -0
  235. package/src/components/table/QTr.js +4 -1
  236. package/src/components/table/table-sort.js +1 -1
  237. package/src/components/tabs/QTabs.js +2 -2
  238. package/src/components/tabs/use-tab.js +4 -4
  239. package/src/components/time/QTime.js +1 -1
  240. package/src/components/tree/QTree.js +2 -3
  241. package/src/components/virtual-scroll/use-virtual-scroll.js +3 -3
  242. package/src/composables/private.use-field/use-field.js +5 -5
  243. package/src/composables/private.use-file/use-file.js +6 -3
  244. package/src/composables/private.use-model-toggle/use-model-toggle.js +2 -2
  245. package/src/composables/private.use-refocus-target/use-refocus-target.js +6 -5
  246. package/src/composables/private.use-validate/use-validate.js +1 -1
  247. package/src/directives/intersection/Intersection.js +2 -2
  248. package/src/directives/morph/Morph.js +2 -2
  249. package/src/directives/mutation/Mutation.js +2 -2
  250. package/src/directives/touch-hold/TouchHold.js +2 -2
  251. package/src/directives/touch-pan/TouchPan.js +2 -2
  252. package/src/directives/touch-repeat/TouchRepeat.js +3 -3
  253. package/src/directives/touch-swipe/TouchSwipe.js +3 -3
  254. package/src/plugins/lang/Lang.test.js +12 -0
  255. package/src/plugins/loading/Loading.js +1 -1
  256. package/src/plugins/notify/Notify.js +1 -1
  257. package/src/plugins/private.body/Body.js +1 -1
  258. package/src/plugins/private.history/History.js +1 -1
  259. package/src/plugins/screen/Screen.js +1 -1
  260. package/src/utils/morph/morph.js +13 -10
  261. package/src/utils/open-url/open-url.js +3 -3
  262. package/src/utils/private.dialog/create-dialog.js +2 -2
  263. package/src/utils/private.portal/portal.js +1 -1
  264. package/src/components/date/__tests__/QDate.cy.js +0 -189
  265. package/src/components/date/__tests__/use-datetime.cy.js +0 -83
  266. package/src/components/editor/__tests__/QEditor.cy.js +0 -195
  267. package/src/components/field/__tests__/QField.cy.js +0 -156
  268. package/src/components/input/__tests__/QInput.cy.js +0 -786
  269. package/src/components/input/__tests__/use-mask.cy.js +0 -124
  270. package/src/components/menu/__tests__/QMenu.cy.js +0 -634
  271. package/src/components/menu/__tests__/WrapperOne.vue +0 -51
  272. package/src/components/menu/__tests__/WrapperTwo.vue +0 -38
  273. package/src/components/select/__tests__/QSelect.cy.js +0 -2018
  274. package/src/components/table/__tests__/QTable.cy.js +0 -635
  275. package/src/components/table/__tests__/QTd.cy.js +0 -35
  276. package/src/components/table/__tests__/QTh.cy.js +0 -27
  277. package/src/components/table/__tests__/QTr.cy.js +0 -27
  278. package/src/components/tabs/__tests__/QTab.cy.js +0 -79
  279. package/src/components/tabs/__tests__/QTabs.cy.js +0 -147
  280. package/src/components/uploader/__tests__/QUploader.cy.js +0 -191
  281. package/src/composables/__tests__/FieldWrapper.vue +0 -54
  282. package/src/composables/__tests__/use-anchor.cy.js +0 -98
  283. package/src/composables/__tests__/use-field.cy.js +0 -547
  284. package/src/composables/__tests__/use-file.cy.js +0 -69
  285. package/src/composables/__tests__/use-fullscreen.cy.js +0 -37
  286. package/src/composables/__tests__/use-model-toggle.cy.js +0 -350
  287. package/src/composables/__tests__/use-portal.cy.js +0 -4
  288. package/src/composables/__tests__/use-router-link.cy.js +0 -55
  289. package/src/composables/__tests__/use-validate.cy.js +0 -257
@@ -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())
@@ -563,6 +563,50 @@
563
563
  "category": "style"
564
564
  },
565
565
 
566
+ "table-row-style-fn": {
567
+ "type": "Function",
568
+ "desc": "CSS style to apply to the table rows (which are TR elements); For best performance, reference it from your scope and do not define it inline",
569
+ "params": {
570
+ "row": {
571
+ "type": "Object",
572
+ "desc": "The current row being processed",
573
+ "examples": [ "{ name: 'Frozen Yogurt', calories: 159 }" ]
574
+ }
575
+ },
576
+ "returns": {
577
+ "type": "String",
578
+ "desc": "CSS style to apply to the row",
579
+ "examples": [
580
+ "'color: blue'",
581
+ "'background-color: #ff0000; color: green'"
582
+ ]
583
+ },
584
+ "category": "style",
585
+ "addedIn": "v2.18"
586
+ },
587
+
588
+ "table-row-class-fn": {
589
+ "type": "Function",
590
+ "desc": "CSS class(es) to apply the table rows (which are TR elements); For best performance, reference it from your scope and do not define it inline",
591
+ "params": {
592
+ "row": {
593
+ "type": "Object",
594
+ "desc": "The current row being processed",
595
+ "examples": [ "{ name: 'Frozen Yogurt', calories: 159 }" ]
596
+ }
597
+ },
598
+ "returns": {
599
+ "type": "String",
600
+ "desc": "CSS class(es) to apply to the row, space separated",
601
+ "examples": [
602
+ "'my-special-class'",
603
+ "'my-class my-second-class'"
604
+ ]
605
+ },
606
+ "category": "style",
607
+ "addedIn": "v2.18"
608
+ },
609
+
566
610
  "card-container-style": {
567
611
  "type": [ "String", "Array", "Object" ],
568
612
  "tsType": "VueStyleProp",
@@ -608,6 +652,50 @@
608
652
  "category": "style"
609
653
  },
610
654
 
655
+ "card-style-fn": {
656
+ "type": "Function",
657
+ "desc": "(Grid mode only) CSS style to apply to the row/record card; Has no effect when the 'item' slot is used; For best performance, reference it from your scope and do not define it inline",
658
+ "params": {
659
+ "row": {
660
+ "type": "Object",
661
+ "desc": "The current row/record being processed",
662
+ "examples": [ "{ name: 'Frozen Yogurt', calories: 159 }" ]
663
+ }
664
+ },
665
+ "returns": {
666
+ "type": "String",
667
+ "desc": "CSS style to apply to the row/record",
668
+ "examples": [
669
+ "'color: blue'",
670
+ "'background-color: #ff0000; color: green'"
671
+ ]
672
+ },
673
+ "category": "style",
674
+ "addedIn": "v2.18"
675
+ },
676
+
677
+ "card-class-fn": {
678
+ "type": "Function",
679
+ "desc": "(Grid mode only) CSS class(es) to apply the row/record card; Has no effect when the 'item' slot is used; For best performance, reference it from your scope and do not define it inline",
680
+ "params": {
681
+ "row": {
682
+ "type": "Object",
683
+ "desc": "The current row/record being processed",
684
+ "examples": [ "{ name: 'Frozen Yogurt', calories: 159 }" ]
685
+ }
686
+ },
687
+ "returns": {
688
+ "type": "String",
689
+ "desc": "CSS class(es) to apply to the row, space separated",
690
+ "examples": [
691
+ "'my-special-class'",
692
+ "'my-class my-second-class'"
693
+ ]
694
+ },
695
+ "category": "style",
696
+ "addedIn": "v2.18"
697
+ },
698
+
611
699
  "title-class": {
612
700
  "type": [ "String", "Array", "Object" ],
613
701
  "tsType": "VueClassProp",
@@ -896,6 +984,12 @@
896
984
  "__trClass": {
897
985
  "type": "String",
898
986
  "desc": "Internal prop passed down to QTr (if used)"
987
+ },
988
+ "__trStyle": {
989
+ "type": "String",
990
+ "required": false,
991
+ "desc": "Internal prop passed down to QTr (if used)",
992
+ "addedIn": "v2.18"
899
993
  }
900
994
  }
901
995
  },
@@ -1838,6 +1932,10 @@
1838
1932
  "type": "String",
1839
1933
  "desc": "The suggested icon name (following Quasar convention)",
1840
1934
  "examples": [ "'warning'" ]
1935
+ },
1936
+ "filter": {
1937
+ "type": [ "String", "Object" ],
1938
+ "desc": "String/Object to filter table with (the 'filter' prop)"
1841
1939
  }
1842
1940
  }
1843
1941
  }
@@ -18,6 +18,9 @@ export default createComponent({
18
18
  + (props.noHover === true ? ' q-tr--no-hover' : '')
19
19
  )
20
20
 
21
- return () => h('tr', { class: classes.value }, hSlot(slots.default))
21
+ return () => h('tr', {
22
+ style: props.props?.__trStyle,
23
+ class: classes.value
24
+ }, hSlot(slots.default))
22
25
  }
23
26
  })
@@ -87,7 +87,7 @@ export function useTableSort (props, computedPagination, colList, setPagination)
87
87
  }
88
88
  else {
89
89
  const def = colList.value.find(def => def.name === col)
90
- if (def !== void 0 && def.sortOrder) {
90
+ if (def?.sortOrder) {
91
91
  sortOrder = def.sortOrder
92
92
  }
93
93
  }
@@ -424,7 +424,7 @@ export default createComponent({
424
424
  function updateActiveRoute () {
425
425
  let name = null, bestScore = { matchedLen: 0, queryDiff: 9999, hrefLen: 0 }
426
426
 
427
- const list = tabDataList.filter(tab => tab.routeData !== void 0 && tab.routeData.hasRouterLink.value === true)
427
+ const list = tabDataList.filter(tab => tab.routeData?.hasRouterLink.value === true)
428
428
  const { hash: currentHash, query: currentQuery } = proxy.$route
429
429
  const currentQueryLen = Object.keys(currentQuery).length
430
430
 
@@ -632,7 +632,7 @@ export default createComponent({
632
632
  function cleanup () {
633
633
  animateTimer !== null && clearTimeout(animateTimer)
634
634
  stopAnimScroll()
635
- unwatchRoute !== void 0 && unwatchRoute()
635
+ unwatchRoute?.()
636
636
  }
637
637
 
638
638
  let hadRouteWatcher, hadActivated
@@ -99,13 +99,13 @@ export default function (props, slots, emit, routeData) {
99
99
  ))
100
100
 
101
101
  function onClick (e, keyboard) {
102
- if (keyboard !== true && blurTargetRef.value !== null) {
103
- blurTargetRef.value.focus()
102
+ if (keyboard !== true && e?.qAvoidFocus !== true) {
103
+ blurTargetRef.value?.focus()
104
104
  }
105
105
 
106
106
  if (props.disable === true) {
107
107
  // we should hinder native navigation though
108
- if (routeData !== void 0 && routeData.hasRouterLink.value === true) {
108
+ if (routeData?.hasRouterLink.value === true) {
109
109
  stopAndPrevent(e)
110
110
  }
111
111
  return
@@ -140,7 +140,7 @@ export default function (props, slots, emit, routeData) {
140
140
  if (
141
141
  hardError === void 0 && (
142
142
  softError === void 0
143
- || (softError.message !== void 0 && softError.message.startsWith('Avoided redundant navigation') === true)
143
+ || (softError.message?.startsWith('Avoided redundant navigation') === true)
144
144
  )
145
145
  ) {
146
146
  $tabs.updateModel({ name: props.name })
@@ -264,7 +264,7 @@ export default createComponent({
264
264
  for (let val = start, index = start; val <= end; val += step, index++) {
265
265
  const
266
266
  actualVal = val + offset,
267
- disable = values !== void 0 && values.includes(actualVal) === false,
267
+ disable = values?.includes(actualVal) === false,
268
268
  label = view.value === 'hour' && val === 0
269
269
  ? (computedFormat24h.value === true ? '00' : '12')
270
270
  : val
@@ -334,7 +334,7 @@ export default createComponent({
334
334
  node[ props.childrenKey ] = Array.isArray(children) === true ? children : []
335
335
  nextTick(() => {
336
336
  const localMeta = meta.value[ key ]
337
- if (localMeta && localMeta.isParent === true) {
337
+ if (localMeta?.isParent === true) {
338
338
  localSetExpanded(key, true)
339
339
  }
340
340
  })
@@ -627,8 +627,7 @@ export default createComponent({
627
627
  }
628
628
 
629
629
  function blur (key) {
630
- const blurTarget = blurTargets[ key ]
631
- blurTarget && blurTarget.focus()
630
+ blurTargets[ key ]?.focus()
632
631
  }
633
632
 
634
633
  function onClick (node, meta, e, keyboard) {
@@ -40,7 +40,7 @@ const setOverflowAnchor = __QUASAR_SSR__ || window.getComputedStyle(document.bod
40
40
 
41
41
  const el = children[ index ]
42
42
 
43
- if (el && el.dataset) {
43
+ if (el?.dataset) {
44
44
  el.dataset.qVsAnchor = ''
45
45
  }
46
46
  })
@@ -422,7 +422,7 @@ export function useVirtualScroll ({
422
422
  contentEl.addEventListener('focusout', onBlurRefocusFn)
423
423
 
424
424
  setTimeout(() => {
425
- contentEl !== null && contentEl.removeEventListener('focusout', onBlurRefocusFn)
425
+ contentEl?.removeEventListener('focusout', onBlurRefocusFn)
426
426
  })
427
427
  }
428
428
 
@@ -533,7 +533,7 @@ export function useVirtualScroll ({
533
533
  }
534
534
 
535
535
  function onBlurRefocusFn () {
536
- contentRef.value !== null && contentRef.value !== void 0 && contentRef.value.focus()
536
+ contentRef.value?.focus()
537
537
  }
538
538
 
539
539
  function localResetVirtualScroll (toIndex, fullReset) {
@@ -265,12 +265,12 @@ export default function (state) {
265
265
 
266
266
  function focusHandler () {
267
267
  const el = document.activeElement
268
- let target = state.targetRef !== void 0 && state.targetRef.value
268
+ let target = state.targetRef?.value
269
269
 
270
270
  if (target && (el === null || el.id !== state.targetUid.value)) {
271
271
  target.hasAttribute('tabindex') === true || (target = target.querySelector('[tabindex]'))
272
- if (target && target !== el) {
273
- target.focus({ preventScroll: true })
272
+ if (target !== el) {
273
+ target?.focus({ preventScroll: true })
274
274
  }
275
275
  }
276
276
  }
@@ -318,7 +318,7 @@ export default function (state) {
318
318
  emit('blur', e)
319
319
  }
320
320
 
321
- then !== void 0 && then()
321
+ then?.()
322
322
  })
323
323
  }
324
324
 
@@ -327,7 +327,7 @@ export default function (state) {
327
327
  stopAndPrevent(e)
328
328
 
329
329
  if ($q.platform.is.mobile !== true) {
330
- const el = (state.targetRef !== void 0 && state.targetRef.value) || state.rootRef.value
330
+ const el = state.targetRef?.value || state.rootRef.value
331
331
  el.focus()
332
332
  }
333
333
  else if (state.rootRef.value.contains(document.activeElement) === true) {
@@ -19,7 +19,10 @@ function filterFiles (files, rejectedFiles, failedPropValidation, filterFn) {
19
19
  }
20
20
 
21
21
  function stopAndPreventDrag (e) {
22
- e && e.dataTransfer && (e.dataTransfer.dropEffect = 'copy')
22
+ if (e?.dataTransfer) {
23
+ e.dataTransfer.dropEffect = 'copy'
24
+ }
25
+
23
26
  stopAndPrevent(e)
24
27
  }
25
28
 
@@ -69,13 +72,13 @@ export default function ({
69
72
  e = { target: null }
70
73
  }
71
74
 
72
- if (e.target !== null && e.target.matches('input[type="file"]') === true) {
75
+ if (e.target?.matches('input[type="file"]') === true) {
73
76
  // stop propagation if it's not a real pointer event
74
77
  e.clientX === 0 && e.clientY === 0 && stop(e)
75
78
  }
76
79
  else {
77
80
  const input = getFileInput()
78
- input && input !== e.target && input.click(e)
81
+ if (input !== e.target) input?.click(e)
79
82
  }
80
83
  }
81
84
  }
@@ -41,8 +41,8 @@ export default function ({
41
41
 
42
42
  function show (evt) {
43
43
  if (
44
- props.disable === true
45
- || (evt !== void 0 && evt.qAnchorHandled === true)
44
+ (props.disable === true)
45
+ || (evt?.qAnchorHandled === true)
46
46
  || (canShow !== void 0 && canShow(evt) !== true)
47
47
  ) return
48
48
 
@@ -18,18 +18,19 @@ export default function (props, rootRef) {
18
18
  function refocusTarget (e) {
19
19
  const root = rootRef.value
20
20
 
21
- if (e !== void 0 && e.type.indexOf('key') === 0) {
21
+ if (e?.qAvoidFocus === true) return
22
+
23
+ if (e?.type.indexOf('key') === 0) {
22
24
  if (
23
- root !== null
24
- && document.activeElement !== root
25
- && root.contains(document.activeElement) === true
25
+ document.activeElement !== root
26
+ && root?.contains(document.activeElement) === true
26
27
  ) {
27
28
  root.focus()
28
29
  }
29
30
  }
30
31
  else if (
31
32
  refocusRef.value !== null
32
- && (e === void 0 || (root !== null && root.contains(e.target) === true))
33
+ && ((e === void 0) || (root?.contains(e.target) === true))
33
34
  ) {
34
35
  refocusRef.value.focus()
35
36
  }
@@ -201,7 +201,7 @@ export default function (focused, innerLoading) {
201
201
  const debouncedValidate = debounce(validate, 0)
202
202
 
203
203
  onBeforeUnmount(() => {
204
- unwatchRules !== void 0 && unwatchRules()
204
+ unwatchRules?.()
205
205
  debouncedValidate.cancel()
206
206
  })
207
207
 
@@ -28,7 +28,7 @@ function update (el, ctx, value) {
28
28
 
29
29
  if (changed === true) {
30
30
  ctx.cfg = cfg
31
- ctx.observer !== void 0 && ctx.observer.unobserve(el)
31
+ ctx.observer?.unobserve(el)
32
32
 
33
33
  ctx.observer = new IntersectionObserver(([ entry ]) => {
34
34
  if (typeof ctx.handler === 'function') {
@@ -62,7 +62,7 @@ function destroy (el) {
62
62
  const ctx = el.__qvisible
63
63
 
64
64
  if (ctx !== void 0) {
65
- ctx.observer !== void 0 && ctx.observer.unobserve(el)
65
+ ctx.observer?.unobserve(el)
66
66
  delete el.__qvisible
67
67
  }
68
68
  }
@@ -44,7 +44,7 @@ function trigger (group) {
44
44
  },
45
45
  ...to.opts,
46
46
  onEnd (dir, aborted) {
47
- to.opts.onEnd !== void 0 && to.opts.onEnd(dir, aborted)
47
+ to.opts.onEnd?.(dir, aborted)
48
48
 
49
49
  if (aborted === true) return
50
50
 
@@ -206,7 +206,7 @@ export default createDirective(__QUASAR_SSR_SERVER__
206
206
  group.queue = group.queue.filter(item => item !== ctx)
207
207
 
208
208
  if (group.queue.length === 0) {
209
- group.cancel !== void 0 && group.cancel()
209
+ group.cancel?.()
210
210
  delete morphGroups[ ctx.group ]
211
211
  }
212
212
  }
@@ -12,7 +12,7 @@ const defaultCfg = {
12
12
 
13
13
  function update (el, ctx, value) {
14
14
  ctx.handler = value
15
- ctx.observer !== void 0 && ctx.observer.disconnect()
15
+ ctx.observer?.disconnect()
16
16
 
17
17
  ctx.observer = new MutationObserver(list => {
18
18
  if (typeof ctx.handler === 'function') {
@@ -30,7 +30,7 @@ function destroy (el) {
30
30
  const ctx = el.__qmutation
31
31
 
32
32
  if (ctx !== void 0) {
33
- ctx.observer !== void 0 && ctx.observer.disconnect()
33
+ ctx.observer?.disconnect()
34
34
  delete el.__qmutation
35
35
  }
36
36
  }
@@ -106,7 +106,7 @@ export default createDirective(__QUASAR_SSR_SERVER__
106
106
  cleanEvt(ctx, 'temp')
107
107
 
108
108
  // delay needed otherwise selection still occurs
109
- ctx.styleCleanup !== void 0 && ctx.styleCleanup(ctx.triggered)
109
+ ctx.styleCleanup?.(ctx.triggered)
110
110
 
111
111
  if (ctx.triggered === true) {
112
112
  evt !== void 0 && stopAndPrevent(evt)
@@ -166,7 +166,7 @@ export default createDirective(__QUASAR_SSR_SERVER__
166
166
  cleanEvt(ctx, 'temp')
167
167
 
168
168
  ctx.timer !== void 0 && clearTimeout(ctx.timer)
169
- ctx.styleCleanup !== void 0 && ctx.styleCleanup()
169
+ ctx.styleCleanup?.()
170
170
 
171
171
  delete el.__qtouchhold
172
172
  }
@@ -355,7 +355,7 @@ export default createDirective(__QUASAR_SSR_SERVER__
355
355
  client.is.firefox === true && preventDraggable(el, false)
356
356
 
357
357
  if (abort === true) {
358
- ctx.styleCleanup !== void 0 && ctx.styleCleanup()
358
+ ctx.styleCleanup?.()
359
359
 
360
360
  if (ctx.event.detected !== true && ctx.initialEvent !== void 0) {
361
361
  ctx.initialEvent.target.dispatchEvent(ctx.initialEvent.event)
@@ -426,7 +426,7 @@ export default createDirective(__QUASAR_SSR_SERVER__
426
426
  cleanEvt(ctx, 'temp')
427
427
 
428
428
  client.is.firefox === true && preventDraggable(el, false)
429
- ctx.styleCleanup !== void 0 && ctx.styleCleanup()
429
+ ctx.styleCleanup?.()
430
430
 
431
431
  delete el.__qtouchpan
432
432
  }