quasar 2.21.4 → 2.22.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 (178) hide show
  1. package/README.md +1 -1
  2. package/dist/api/QUploader.json +1 -1
  3. package/dist/icon-set/bootstrap-icons.umd.prod.js +1 -1
  4. package/dist/icon-set/eva-icons.umd.prod.js +1 -1
  5. package/dist/icon-set/fontawesome-v5-pro.umd.prod.js +1 -1
  6. package/dist/icon-set/fontawesome-v5.umd.prod.js +1 -1
  7. package/dist/icon-set/fontawesome-v6-pro.umd.prod.js +1 -1
  8. package/dist/icon-set/fontawesome-v6.umd.prod.js +1 -1
  9. package/dist/icon-set/fontawesome-v7-pro.umd.prod.js +1 -1
  10. package/dist/icon-set/fontawesome-v7.umd.prod.js +1 -1
  11. package/dist/icon-set/ionicons-v4.umd.prod.js +1 -1
  12. package/dist/icon-set/line-awesome.umd.prod.js +1 -1
  13. package/dist/icon-set/material-icons-outlined.umd.prod.js +1 -1
  14. package/dist/icon-set/material-icons-round.umd.prod.js +1 -1
  15. package/dist/icon-set/material-icons-sharp.umd.prod.js +1 -1
  16. package/dist/icon-set/material-icons.umd.prod.js +1 -1
  17. package/dist/icon-set/material-symbols-outlined.umd.prod.js +1 -1
  18. package/dist/icon-set/material-symbols-rounded.umd.prod.js +1 -1
  19. package/dist/icon-set/material-symbols-sharp.umd.prod.js +1 -1
  20. package/dist/icon-set/mdi-v3.umd.prod.js +1 -1
  21. package/dist/icon-set/mdi-v4.umd.prod.js +1 -1
  22. package/dist/icon-set/mdi-v5.umd.prod.js +1 -1
  23. package/dist/icon-set/mdi-v6.umd.prod.js +1 -1
  24. package/dist/icon-set/mdi-v7.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-fontawesome-v7.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-ionicons-v7.umd.prod.js +1 -1
  34. package/dist/icon-set/svg-ionicons-v8.umd.prod.js +1 -1
  35. package/dist/icon-set/svg-line-awesome.umd.prod.js +1 -1
  36. package/dist/icon-set/svg-material-icons-outlined.umd.prod.js +1 -1
  37. package/dist/icon-set/svg-material-icons-round.umd.prod.js +1 -1
  38. package/dist/icon-set/svg-material-icons-sharp.umd.prod.js +1 -1
  39. package/dist/icon-set/svg-material-icons.umd.prod.js +1 -1
  40. package/dist/icon-set/svg-material-symbols-outlined.umd.prod.js +1 -1
  41. package/dist/icon-set/svg-material-symbols-rounded.umd.prod.js +1 -1
  42. package/dist/icon-set/svg-material-symbols-sharp.umd.prod.js +1 -1
  43. package/dist/icon-set/svg-mdi-v6.umd.prod.js +1 -1
  44. package/dist/icon-set/svg-mdi-v7.umd.prod.js +1 -1
  45. package/dist/icon-set/svg-themify.umd.prod.js +1 -1
  46. package/dist/icon-set/themify.umd.prod.js +1 -1
  47. package/dist/lang/ar-TN.umd.prod.js +1 -1
  48. package/dist/lang/ar.umd.prod.js +1 -1
  49. package/dist/lang/az-Latn.umd.prod.js +1 -1
  50. package/dist/lang/bg.umd.prod.js +1 -1
  51. package/dist/lang/bn.umd.prod.js +1 -1
  52. package/dist/lang/bs-BA.umd.prod.js +1 -1
  53. package/dist/lang/ca.umd.prod.js +1 -1
  54. package/dist/lang/cs.umd.prod.js +1 -1
  55. package/dist/lang/da.umd.prod.js +1 -1
  56. package/dist/lang/de-CH.umd.prod.js +1 -1
  57. package/dist/lang/de-DE.umd.prod.js +1 -1
  58. package/dist/lang/de.umd.prod.js +1 -1
  59. package/dist/lang/el.umd.prod.js +1 -1
  60. package/dist/lang/en-GB.umd.prod.js +1 -1
  61. package/dist/lang/en-US.umd.prod.js +1 -1
  62. package/dist/lang/eo.umd.prod.js +1 -1
  63. package/dist/lang/es.umd.prod.js +1 -1
  64. package/dist/lang/et.umd.prod.js +1 -1
  65. package/dist/lang/eu.umd.prod.js +1 -1
  66. package/dist/lang/fa-IR.umd.prod.js +1 -1
  67. package/dist/lang/fa.umd.prod.js +1 -1
  68. package/dist/lang/fi.umd.prod.js +1 -1
  69. package/dist/lang/fr.umd.prod.js +1 -1
  70. package/dist/lang/gn.umd.prod.js +1 -1
  71. package/dist/lang/he.umd.prod.js +1 -1
  72. package/dist/lang/hi.umd.prod.js +1 -1
  73. package/dist/lang/hr.umd.prod.js +1 -1
  74. package/dist/lang/hu.umd.prod.js +1 -1
  75. package/dist/lang/id.umd.prod.js +1 -1
  76. package/dist/lang/is.umd.prod.js +1 -1
  77. package/dist/lang/it.umd.prod.js +1 -1
  78. package/dist/lang/ja.umd.prod.js +1 -1
  79. package/dist/lang/kk.umd.prod.js +1 -1
  80. package/dist/lang/km.umd.prod.js +1 -1
  81. package/dist/lang/ko-KR.umd.prod.js +1 -1
  82. package/dist/lang/kur-CKB.umd.prod.js +1 -1
  83. package/dist/lang/lb.umd.prod.js +1 -1
  84. package/dist/lang/lt.umd.prod.js +1 -1
  85. package/dist/lang/lu.umd.prod.js +1 -1
  86. package/dist/lang/lv.umd.prod.js +1 -1
  87. package/dist/lang/mk.umd.prod.js +1 -1
  88. package/dist/lang/ml.umd.prod.js +1 -1
  89. package/dist/lang/mm.umd.prod.js +1 -1
  90. package/dist/lang/ms-MY.umd.prod.js +1 -1
  91. package/dist/lang/ms.umd.prod.js +1 -1
  92. package/dist/lang/my.umd.prod.js +1 -1
  93. package/dist/lang/nb-NO.umd.prod.js +1 -1
  94. package/dist/lang/nl.umd.prod.js +1 -1
  95. package/dist/lang/pl.umd.prod.js +1 -1
  96. package/dist/lang/pt-BR.umd.prod.js +1 -1
  97. package/dist/lang/pt.umd.prod.js +1 -1
  98. package/dist/lang/ro.umd.prod.js +1 -1
  99. package/dist/lang/ru.umd.prod.js +1 -1
  100. package/dist/lang/sk.umd.prod.js +1 -1
  101. package/dist/lang/sl.umd.prod.js +1 -1
  102. package/dist/lang/sm.umd.prod.js +1 -1
  103. package/dist/lang/sq.umd.prod.js +1 -1
  104. package/dist/lang/sr-CYR.umd.prod.js +1 -1
  105. package/dist/lang/sr.umd.prod.js +1 -1
  106. package/dist/lang/sv.umd.prod.js +1 -1
  107. package/dist/lang/ta.umd.prod.js +1 -1
  108. package/dist/lang/th.umd.prod.js +1 -1
  109. package/dist/lang/tl.umd.prod.js +1 -1
  110. package/dist/lang/tr.umd.prod.js +1 -1
  111. package/dist/lang/ug.umd.prod.js +1 -1
  112. package/dist/lang/uk.umd.prod.js +1 -1
  113. package/dist/lang/ur-PK.umd.prod.js +1 -1
  114. package/dist/lang/uz-Cyrl.umd.prod.js +1 -1
  115. package/dist/lang/uz-Latn.umd.prod.js +1 -1
  116. package/dist/lang/vi.umd.prod.js +1 -1
  117. package/dist/lang/zh-CN.umd.prod.js +1 -1
  118. package/dist/lang/zh-TW.umd.prod.js +1 -1
  119. package/dist/quasar.client.js +572 -187
  120. package/dist/quasar.css +4 -0
  121. package/dist/quasar.prod.css +1 -1
  122. package/dist/quasar.rtl.css +5 -0
  123. package/dist/quasar.rtl.prod.css +1 -1
  124. package/dist/quasar.sass +4 -1
  125. package/dist/quasar.server.prod.cjs +35 -35
  126. package/dist/quasar.server.prod.js +25 -25
  127. package/dist/quasar.umd.js +572 -187
  128. package/dist/quasar.umd.prod.js +30 -30
  129. package/dist/types/composables.d.ts +10 -5
  130. package/dist/types/index.d.ts +4 -4
  131. package/dist/web-types/web-types.json +1 -1
  132. package/package.json +6 -6
  133. package/src/components/carousel/QCarousel.js +2 -0
  134. package/src/components/chip/QChip.js +20 -4
  135. package/src/components/date/QDate.js +9 -2
  136. package/src/components/dialog/QDialog.js +9 -2
  137. package/src/components/editor/QEditor.js +18 -3
  138. package/src/components/expansion-item/QExpansionItem.js +6 -1
  139. package/src/components/input/QInput.js +42 -1
  140. package/src/components/input/QInput.json +7 -0
  141. package/src/components/input/use-mask.js +12 -4
  142. package/src/components/item/QItem.js +10 -1
  143. package/src/components/menu/QMenu.js +9 -2
  144. package/src/components/range/QRange.js +2 -1
  145. package/src/components/rating/QRating.js +27 -8
  146. package/src/components/rating/QRating.sass +4 -0
  147. package/src/components/resize-observer/QResizeObserver.js +14 -3
  148. package/src/components/scroll-area/QScrollArea.js +69 -17
  149. package/src/components/slide-item/QSlideItem.js +3 -2
  150. package/src/components/slider/use-slider.js +7 -3
  151. package/src/components/stepper/StepHeader.js +11 -2
  152. package/src/components/table/QTable.js +11 -9
  153. package/src/components/table/QTh.js +20 -1
  154. package/src/components/table/table-column-selection.js +9 -1
  155. package/src/components/table/table-pagination.js +5 -2
  156. package/src/components/table/table-row-selection.js +10 -10
  157. package/src/components/tabs/QTabs.js +5 -6
  158. package/src/components/time/QTime.js +35 -10
  159. package/src/components/tooltip/QTooltip.js +112 -6
  160. package/src/components/tree/QTree.js +124 -4
  161. package/src/components/uploader/uploader-core.js +19 -4
  162. package/src/components/uploader/xhr-uploader-plugin.js +93 -43
  163. package/src/components/uploader/xhr-uploader-plugin.json +4 -4
  164. package/src/composables/private.use-field/use-field.js +2 -0
  165. package/src/composables/private.use-file/use-file.js +21 -12
  166. package/src/composables/private.use-fullscreen/use-fullscreen.js +8 -3
  167. package/src/composables/private.use-model-toggle/use-model-toggle.js +2 -0
  168. package/src/composables/private.use-panel/use-panel.js +6 -2
  169. package/src/composables/use-interval/use-interval.js +8 -0
  170. package/src/composables/use-render-cache/use-render-cache.js +15 -10
  171. package/src/composables/use-timeout/use-timeout.js +8 -0
  172. package/src/directives/intersection/Intersection.js +2 -2
  173. package/src/directives/touch-repeat/TouchRepeat.js +3 -1
  174. package/src/plugins/cookies/Cookies.js +29 -13
  175. package/src/plugins/meta/Meta.js +57 -9
  176. package/src/utils/extend/extend.js +4 -0
  177. package/src/utils/extend/extend.test.js +29 -0
  178. package/src/utils/scroll/prevent-scroll.js +4 -4
@@ -26,6 +26,7 @@ import {
26
26
  setVerticalScrollPosition
27
27
  } from '../../utils/scroll/scroll.js'
28
28
  import { hMergeSlot } from '../../utils/private.render/render.js'
29
+ import { rtlHasScrollBug } from '../../utils/private.rtl/rtl.js'
29
30
  import debounce from '../../utils/debounce/debounce.js'
30
31
 
31
32
  const axisList = ['vertical', 'horizontal']
@@ -62,11 +63,11 @@ export default createComponent({
62
63
 
63
64
  verticalOffset: {
64
65
  type: Array,
65
- default: [0, 0]
66
+ default: () => [0, 0]
66
67
  },
67
68
  horizontalOffset: {
68
69
  type: Array,
69
- default: [0, 0]
70
+ default: () => [0, 0]
70
71
  },
71
72
 
72
73
  contentStyle: [Array, String, Object],
@@ -200,7 +201,11 @@ export default createComponent({
200
201
  if (diff <= 0) {
201
202
  return 0
202
203
  }
203
- const p = between(Math.abs(scroll.horizontal.position.value) / diff, 0, 1)
204
+ const p = between(
205
+ getHorizontalLogicalPosition(scroll.horizontal.position.value) / diff,
206
+ 0,
207
+ 1
208
+ )
204
209
  return Math.round(p * 10_000) / 10_000
205
210
  })
206
211
  scroll.horizontal.thumbHidden = computed(
@@ -212,7 +217,7 @@ export default createComponent({
212
217
  )
213
218
  scroll.horizontal.thumbStart = computed(
214
219
  () =>
215
- props.horizontalOffset[0] +
220
+ props.horizontalOffset[proxy.$q.lang.rtl ? 1 : 0] +
216
221
  scroll.horizontal.percentage.value *
217
222
  (container.horizontalInner.value - scroll.horizontal.thumbSize.value)
218
223
  )
@@ -347,7 +352,10 @@ export default createComponent({
347
352
  if (e.isFirst) {
348
353
  if (data.thumbHidden.value) return
349
354
 
350
- panRefPos = data.position.value
355
+ panRefPos =
356
+ axis === 'horizontal'
357
+ ? getHorizontalLogicalPosition(data.position.value)
358
+ : data.position.value
351
359
  panning.value = true
352
360
  } else if (!panning.value) {
353
361
  return
@@ -361,22 +369,31 @@ export default createComponent({
361
369
  (data.size.value - container[axis].value) /
362
370
  (container[axis + 'Inner'].value - data.thumbSize.value)
363
371
  const distance = e.distance[dProp.dist]
364
- const pos =
365
- panRefPos + (e.direction === dProp.dir ? 1 : -1) * distance * multiplier
366
-
367
- setScroll(pos, axis)
372
+ const direction =
373
+ (e.direction === dProp.dir ? 1 : -1) *
374
+ (axis === 'horizontal' && proxy.$q.lang.rtl ? -1 : 1)
375
+ const pos = panRefPos + direction * distance * multiplier
376
+
377
+ setScroll(
378
+ axis === 'horizontal' ? getHorizontalNativePosition(pos) : pos,
379
+ axis
380
+ )
368
381
  }
369
382
 
370
383
  function onMousedown(evt, axis) {
371
384
  const data = scroll[axis]
372
385
 
373
386
  if (!data.thumbHidden.value) {
387
+ const isHorizontalRtl = axis === 'horizontal' && proxy.$q.lang.rtl
374
388
  const startOffset =
375
389
  axis === 'vertical'
376
390
  ? props.verticalOffset[0]
377
- : props.horizontalOffset[0]
391
+ : props.horizontalOffset[isHorizontalRtl ? 1 : 0]
378
392
 
379
- const offset = evt[dirProps[axis].offset] - startOffset
393
+ const pointerOffset = isHorizontalRtl
394
+ ? container.horizontal.value - evt.offsetX
395
+ : evt[dirProps[axis].offset]
396
+ const offset = pointerOffset - startOffset
380
397
  const thumbStart = data.thumbStart.value - startOffset
381
398
 
382
399
  if (offset < thumbStart || offset > thumbStart + data.thumbSize.value) {
@@ -388,7 +405,13 @@ export default createComponent({
388
405
  1
389
406
  )
390
407
  setScroll(
391
- percentage * Math.max(0, data.size.value - container[axis].value),
408
+ isHorizontalRtl
409
+ ? getHorizontalNativePosition(
410
+ percentage *
411
+ Math.max(0, data.size.value - container[axis].value)
412
+ )
413
+ : percentage *
414
+ Math.max(0, data.size.value - container[axis].value),
392
415
  axis
393
416
  )
394
417
  }
@@ -416,6 +439,28 @@ export default createComponent({
416
439
  targetRef.value[dirProps[axis].scroll] = offset
417
440
  }
418
441
 
442
+ function getHorizontalLogicalPosition(position, rtl = proxy.$q.lang.rtl) {
443
+ if (!rtl) return position
444
+
445
+ return rtlHasScrollBug
446
+ ? Math.max(
447
+ 0,
448
+ scroll.horizontal.size.value - container.horizontal.value
449
+ ) - position
450
+ : -position
451
+ }
452
+
453
+ function getHorizontalNativePosition(position, rtl = proxy.$q.lang.rtl) {
454
+ if (!rtl) return position
455
+
456
+ return rtlHasScrollBug
457
+ ? Math.max(
458
+ 0,
459
+ scroll.horizontal.size.value - container.horizontal.value
460
+ ) - position
461
+ : -position
462
+ }
463
+
419
464
  let mouseEventTimer = null
420
465
 
421
466
  function onMouseenter() {
@@ -446,11 +491,17 @@ export default createComponent({
446
491
 
447
492
  watch(
448
493
  () => proxy.$q.lang.rtl,
449
- rtl => {
494
+ (rtl, oldRtl) => {
450
495
  if (targetRef.value !== null) {
451
496
  setHorizontalScrollPosition(
452
497
  targetRef.value,
453
- Math.abs(scroll.horizontal.position.value) * (rtl ? -1 : 1)
498
+ getHorizontalNativePosition(
499
+ getHorizontalLogicalPosition(
500
+ scroll.horizontal.position.value,
501
+ oldRtl
502
+ ),
503
+ rtl
504
+ )
454
505
  )
455
506
  }
456
507
  }
@@ -490,11 +541,12 @@ export default createComponent({
490
541
  }),
491
542
  setScrollPosition: localSetScrollPosition,
492
543
  setScrollPercentage(axis, percentage, duration) {
544
+ const offset =
545
+ percentage * (scroll[axis].size.value - container[axis].value)
546
+
493
547
  localSetScrollPosition(
494
548
  axis,
495
- percentage *
496
- (scroll[axis].size.value - container[axis].value) *
497
- (axis === 'horizontal' && proxy.$q.lang.rtl ? -1 : 1),
549
+ axis === 'horizontal' ? getHorizontalNativePosition(offset) : offset,
498
550
  duration
499
551
  )
500
552
  }
@@ -105,10 +105,11 @@ export default createComponent({
105
105
  node.style.transform = `translate${pan.axis}(${pan.dir * 100}%)`
106
106
 
107
107
  if (timer !== null) clearTimeout(timer)
108
+ const showing = pan.showing
108
109
  timer = setTimeout(() => {
109
110
  timer = null
110
- emit(pan.showing, { reset })
111
- emit('action', { side: pan.showing, reset })
111
+ emit(showing, { reset })
112
+ emit('action', { side: showing, reset })
112
113
  }, 230)
113
114
  } else {
114
115
  node.style.transform = 'translate(0,0)'
@@ -596,10 +596,14 @@ export default function useSlider({
596
596
  ]
597
597
  )
598
598
  )
599
+ }
599
600
 
600
- if (props.name !== void 0 && !props.disable) {
601
- injectFormInput(thumbContent, 'push')
602
- }
601
+ if (
602
+ thumb.injectFormInput !== false &&
603
+ props.name !== void 0 &&
604
+ !props.disable
605
+ ) {
606
+ injectFormInput(thumbContent, 'push')
603
607
  }
604
608
 
605
609
  return h(
@@ -4,6 +4,11 @@ import QIcon from '../icon/QIcon.js'
4
4
  import Ripple from '../../directives/ripple/Ripple.js'
5
5
 
6
6
  import { createComponent } from '../../utils/private.create/create.js'
7
+ import { stopAndPrevent } from '../../utils/event/event.js'
8
+
9
+ function preventSpace(e) {
10
+ if (e.keyCode === 32) stopAndPrevent(e)
11
+ }
7
12
 
8
13
  export default createComponent({
9
14
  name: 'StepHeader',
@@ -134,8 +139,9 @@ export default createComponent({
134
139
  }
135
140
 
136
141
  function onKeyup(e) {
137
- if (e.keyCode === 13 && !isActive.value) {
138
- props.goToPanel(props.step.name)
142
+ if ([13, 32].includes(e.keyCode)) {
143
+ if (!isActive.value) props.goToPanel(props.step.name)
144
+ stopAndPrevent(e)
139
145
  }
140
146
  }
141
147
 
@@ -144,7 +150,10 @@ export default createComponent({
144
150
 
145
151
  if (headerNav.value) {
146
152
  data.onClick = onActivate
153
+ data.onKeydown = preventSpace
147
154
  data.onKeyup = onKeyup
155
+ data.role = 'button'
156
+ data['aria-current'] = isActive.value ? 'step' : void 0
148
157
 
149
158
  Object.assign(
150
159
  data,
@@ -201,15 +201,17 @@ export default createComponent({
201
201
  )
202
202
 
203
203
  watch(
204
- () =>
205
- props.tableStyle +
206
- props.tableClass +
207
- props.tableHeaderStyle +
208
- props.tableHeaderClass +
209
- containerClass.value,
204
+ [
205
+ () => props.tableStyle,
206
+ () => props.tableClass,
207
+ () => props.tableHeaderStyle,
208
+ () => props.tableHeaderClass,
209
+ containerClass
210
+ ],
210
211
  () => {
211
212
  if (hasVirtScroll.value) virtScrollRef.value?.reset()
212
- }
213
+ },
214
+ { deep: true }
213
215
  )
214
216
 
215
217
  const {
@@ -1095,13 +1097,13 @@ export default createComponent({
1095
1097
 
1096
1098
  if (props.onRowClick !== void 0) {
1097
1099
  data.onClick = evt => {
1098
- emit('RowClick', evt, scope.row, scope.pageIndex)
1100
+ emit('rowClick', evt, scope.row, scope.pageIndex)
1099
1101
  }
1100
1102
  }
1101
1103
 
1102
1104
  if (props.onRowDblclick !== void 0) {
1103
1105
  data.onDblclick = evt => {
1104
- emit('RowDblclick', evt, scope.row, scope.pageIndex)
1106
+ emit('rowDblclick', evt, scope.row, scope.pageIndex)
1105
1107
  }
1106
1108
  }
1107
1109
 
@@ -25,6 +25,14 @@ export default createComponent({
25
25
  emit('click', evt)
26
26
  }
27
27
 
28
+ const onKeyup = (evt, col) => {
29
+ if (evt.key === 'Enter' || evt.key === ' ') {
30
+ props.props.sort(col)
31
+ onClick(evt)
32
+ evt.preventDefault()
33
+ }
34
+ }
35
+
28
36
  return () => {
29
37
  if (props.props === void 0) {
30
38
  return h(
@@ -40,7 +48,7 @@ export default createComponent({
40
48
  let col, child
41
49
  const name = vm.vnode.key
42
50
 
43
- if (name) {
51
+ if (name !== null) {
44
52
  col = props.props.colsMap[name]
45
53
  if (col === void 0) return
46
54
  } else {
@@ -71,6 +79,17 @@ export default createComponent({
71
79
  }
72
80
  }
73
81
 
82
+ if (col.sortable) {
83
+ data.tabindex = 0
84
+ data['aria-sort'] = col.__ariaSort
85
+ data.onKeydown = evt => {
86
+ if (evt.key === ' ') evt.preventDefault()
87
+ }
88
+ data.onKeyup = evt => {
89
+ onKeyup(evt, col)
90
+ }
91
+ }
92
+
74
93
  return h('th', data, child)
75
94
  }
76
95
  }
@@ -48,6 +48,14 @@ export function useTableColumnSelection(
48
48
  ...col,
49
49
  align,
50
50
  __iconClass: `q-table__sort-icon q-table__sort-icon--${align}`,
51
+ __ariaSort:
52
+ col.sortable === true
53
+ ? col.name === sortBy
54
+ ? descending
55
+ ? 'descending'
56
+ : 'ascending'
57
+ : 'none'
58
+ : void 0,
51
59
  __thClass:
52
60
  alignClass +
53
61
  (col.headerClasses !== void 0 ? ' ' + col.headerClasses : '') +
@@ -74,7 +82,7 @@ export function useTableColumnSelection(
74
82
  })
75
83
 
76
84
  const computedColsMap = computed(() => {
77
- const names = {}
85
+ const names = Object.create(null)
78
86
  computedCols.value.forEach(col => {
79
87
  names[col.name] = col
80
88
  })
@@ -64,8 +64,11 @@ export function useTablePaginationState(vm, getCellValue) {
64
64
  function requestServerInteraction(prop = {}) {
65
65
  nextTick(() => {
66
66
  emit('request', {
67
- pagination: prop.pagination || computedPagination.value,
68
- filter: prop.filter || props.filter,
67
+ pagination:
68
+ prop.pagination === void 0
69
+ ? computedPagination.value
70
+ : prop.pagination,
71
+ filter: prop.filter === void 0 ? props.filter : prop.filter,
69
72
  getCellValue
70
73
  })
71
74
  })
@@ -15,13 +15,9 @@ export const useTableRowSelectionProps = {
15
15
  export const useTableRowSelectionEmits = ['update:selected', 'selection']
16
16
 
17
17
  export function useTableRowSelection(props, emit, computedRows, getRowKey) {
18
- const selectedKeys = computed(() => {
19
- const keys = {}
20
- props.selected.map(getRowKey.value).forEach(key => {
21
- keys[key] = true
22
- })
23
- return keys
24
- })
18
+ const selectedKeys = computed(
19
+ () => new Set(props.selected.map(getRowKey.value))
20
+ )
25
21
 
26
22
  const hasSelectionMode = computed(() => props.selection !== 'none')
27
23
  const singleSelection = computed(() => props.selection === 'single')
@@ -29,19 +25,23 @@ export function useTableRowSelection(props, emit, computedRows, getRowKey) {
29
25
  const allRowsSelected = computed(
30
26
  () =>
31
27
  computedRows.value.length !== 0 &&
32
- computedRows.value.every(row => selectedKeys.value[getRowKey.value(row)])
28
+ computedRows.value.every(row =>
29
+ selectedKeys.value.has(getRowKey.value(row))
30
+ )
33
31
  )
34
32
 
35
33
  const someRowsSelected = computed(
36
34
  () =>
37
35
  !allRowsSelected.value &&
38
- computedRows.value.some(row => selectedKeys.value[getRowKey.value(row)])
36
+ computedRows.value.some(row =>
37
+ selectedKeys.value.has(getRowKey.value(row))
38
+ )
39
39
  )
40
40
 
41
41
  const rowsSelectedNumber = computed(() => props.selected.length)
42
42
 
43
43
  function isRowSelected(key) {
44
- return selectedKeys.value[key] === true
44
+ return selectedKeys.value.has(key)
45
45
  }
46
46
 
47
47
  function clearSelection() {
@@ -386,13 +386,11 @@ export default createComponent({
386
386
  const dir = dirPrev ? -1 : dirNext ? 1 : void 0
387
387
 
388
388
  if (dir !== void 0) {
389
- const rtlDir = isRTL.value ? -1 : 1
390
- const index = tabs.indexOf(fromEl) + dir * rtlDir
389
+ const rtlDir = props.vertical !== true && isRTL.value ? -1 : 1
390
+ const index = (tabs.indexOf(fromEl) + dir * rtlDir + len) % len
391
391
 
392
- if (index >= 0 && index < len) {
393
- scrollToTabEl(tabs[index])
394
- tabs[index].focus({ preventScroll: true })
395
- }
392
+ scrollToTabEl(tabs[index])
393
+ tabs[index].focus({ preventScroll: true })
396
394
 
397
395
  return true
398
396
  }
@@ -700,6 +698,7 @@ export default createComponent({
700
698
  ref: rootRef,
701
699
  class: classes.value,
702
700
  role: 'tablist',
701
+ 'aria-orientation': props.vertical ? 'vertical' : 'horizontal',
703
702
  onFocusin,
704
703
  onFocusout
705
704
  },
@@ -29,7 +29,7 @@ import useDatetime, {
29
29
  import { createComponent } from '../../utils/private.create/create.js'
30
30
  import { hSlot } from '../../utils/private.render/render.js'
31
31
  import { __splitDate, formatDate } from '../../utils/date/date.js'
32
- import { position } from '../../utils/event/event.js'
32
+ import { position, stopAndPrevent } from '../../utils/event/event.js'
33
33
  import { pad } from '../../utils/format/format.js'
34
34
  import { vmIsDestroyed } from '../../utils/private.vm/vm.js'
35
35
 
@@ -58,6 +58,10 @@ function getCurrentTime() {
58
58
  }
59
59
  }
60
60
 
61
+ function preventSpace(e) {
62
+ if (e.keyCode === 32) stopAndPrevent(e)
63
+ }
64
+
61
65
  function getWheelDist(a, b, threshold) {
62
66
  const diff = Math.abs(a - b)
63
67
  return Math.min(diff, threshold - diff)
@@ -536,11 +540,17 @@ export default createComponent({
536
540
  }
537
541
 
538
542
  function setAmOnKey(e) {
539
- if (e.keyCode === 13) setAm()
543
+ if ([13, 32].includes(e.keyCode)) {
544
+ setAm()
545
+ stopAndPrevent(e)
546
+ }
540
547
  }
541
548
 
542
549
  function setPmOnKey(e) {
543
- if (e.keyCode === 13) setPm()
550
+ if ([13, 32].includes(e.keyCode)) {
551
+ setPm()
552
+ stopAndPrevent(e)
553
+ }
544
554
  }
545
555
 
546
556
  function onClick(evt) {
@@ -562,9 +572,9 @@ export default createComponent({
562
572
  }
563
573
 
564
574
  function onKeyupHour(e) {
565
- if (e.keyCode === 13) {
566
- // ENTER
575
+ if ([13, 32].includes(e.keyCode)) {
567
576
  view.value = 'hour'
577
+ stopAndPrevent(e)
568
578
  } else if ([37, 39].includes(e.keyCode)) {
569
579
  const payload = e.keyCode === 37 ? -1 : 1
570
580
 
@@ -598,9 +608,9 @@ export default createComponent({
598
608
  }
599
609
 
600
610
  function onKeyupMinute(e) {
601
- if (e.keyCode === 13) {
602
- // ENTER
611
+ if ([13, 32].includes(e.keyCode)) {
603
612
  view.value = 'minute'
613
+ stopAndPrevent(e)
604
614
  } else if ([37, 39].includes(e.keyCode)) {
605
615
  const payload = e.keyCode === 37 ? -1 : 1
606
616
 
@@ -631,9 +641,9 @@ export default createComponent({
631
641
  }
632
642
 
633
643
  function onKeyupSecond(e) {
634
- if (e.keyCode === 13) {
635
- // ENTER
644
+ if ([13, 32].includes(e.keyCode)) {
636
645
  view.value = 'second'
646
+ stopAndPrevent(e)
637
647
  } else if ([37, 39].includes(e.keyCode)) {
638
648
  const payload = e.keyCode === 37 ? -1 : 1
639
649
 
@@ -642,7 +652,7 @@ export default createComponent({
642
652
 
643
653
  if (values.length === 0) return
644
654
 
645
- if (innerModel.value.seconds === null) {
655
+ if (innerModel.value.second === null) {
646
656
  setSecond(values[0])
647
657
  } else {
648
658
  const index =
@@ -806,7 +816,10 @@ export default createComponent({
806
816
  ? 'q-time__link--active'
807
817
  : 'cursor-pointer'),
808
818
  tabindex: tabindex.value,
819
+ role: 'button',
820
+ 'aria-pressed': view.value === 'hour' ? 'true' : 'false',
809
821
  onClick: setView.hour,
822
+ onKeydown: preventSpace,
810
823
  onKeyup: onKeyupHour
811
824
  },
812
825
  stringModel.value.hour
@@ -824,6 +837,9 @@ export default createComponent({
824
837
  ? 'q-time__link--active'
825
838
  : 'cursor-pointer'),
826
839
  tabindex: tabindex.value,
840
+ role: 'button',
841
+ 'aria-pressed': view.value === 'minute' ? 'true' : 'false',
842
+ onKeydown: preventSpace,
827
843
  onKeyup: onKeyupMinute,
828
844
  onClick: setView.minute
829
845
  }
@@ -846,6 +862,9 @@ export default createComponent({
846
862
  ? 'q-time__link--active'
847
863
  : 'cursor-pointer'),
848
864
  tabindex: tabindex.value,
865
+ role: 'button',
866
+ 'aria-pressed': view.value === 'second' ? 'true' : 'false',
867
+ onKeydown: preventSpace,
849
868
  onKeyup: onKeyupSecond,
850
869
  onClick: setView.second
851
870
  }
@@ -881,7 +900,10 @@ export default createComponent({
881
900
  'q-time__link ' +
882
901
  (isAM.value ? 'q-time__link--active' : 'cursor-pointer'),
883
902
  tabindex: tabindex.value,
903
+ role: 'button',
904
+ 'aria-pressed': isAM.value ? 'true' : 'false',
884
905
  onClick: setAm,
906
+ onKeydown: preventSpace,
885
907
  onKeyup: setAmOnKey
886
908
  },
887
909
  'AM'
@@ -894,7 +916,10 @@ export default createComponent({
894
916
  'q-time__link ' +
895
917
  (isAM.value ? 'cursor-pointer' : 'q-time__link--active'),
896
918
  tabindex: tabindex.value,
919
+ role: 'button',
920
+ 'aria-pressed': isAM.value ? 'false' : 'true',
897
921
  onClick: setPm,
922
+ onKeydown: preventSpace,
898
923
  onKeyup: setPmOnKey
899
924
  },
900
925
  'PM'