quasar 2.3.3 → 2.4.2

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 (228) hide show
  1. package/dist/api/Dialog.json +1 -1
  2. package/dist/api/Loading.json +2 -6
  3. package/dist/api/QBreadcrumbsEl.json +31 -10
  4. package/dist/api/QBtn.json +30 -14
  5. package/dist/api/QBtnDropdown.json +31 -15
  6. package/dist/api/QBtnToggle.json +3 -0
  7. package/dist/api/QChatMessage.json +4 -12
  8. package/dist/api/QExpansionItem.json +34 -12
  9. package/dist/api/QFab.json +33 -2
  10. package/dist/api/QFabAction.json +8 -0
  11. package/dist/api/QField.json +1 -0
  12. package/dist/api/QFile.json +5 -2
  13. package/dist/api/QForm.json +1 -1
  14. package/dist/api/QInput.json +1 -0
  15. package/dist/api/QItem.json +31 -10
  16. package/dist/api/QOptionGroup.json +74 -4
  17. package/dist/api/QPopupProxy.json +3 -2
  18. package/dist/api/QRange.json +592 -107
  19. package/dist/api/QRating.json +3 -1
  20. package/dist/api/QRouteTab.json +31 -11
  21. package/dist/api/QScrollArea.json +3 -2
  22. package/dist/api/QSelect.json +9 -16
  23. package/dist/api/QSlider.json +504 -39
  24. package/dist/api/QTree.json +8 -4
  25. package/dist/api/QUploader.json +16 -2
  26. package/dist/api/QVirtualScroll.json +3 -2
  27. package/dist/icon-set/bootstrap-icons.umd.prod.js +1 -1
  28. package/dist/icon-set/eva-icons.umd.prod.js +1 -1
  29. package/dist/icon-set/fontawesome-v5-pro.umd.prod.js +1 -1
  30. package/dist/icon-set/fontawesome-v5.umd.prod.js +1 -1
  31. package/dist/icon-set/ionicons-v4.umd.prod.js +1 -1
  32. package/dist/icon-set/line-awesome.umd.prod.js +1 -1
  33. package/dist/icon-set/material-icons-outlined.umd.prod.js +1 -1
  34. package/dist/icon-set/material-icons-round.umd.prod.js +1 -1
  35. package/dist/icon-set/material-icons-sharp.umd.prod.js +1 -1
  36. package/dist/icon-set/material-icons.umd.prod.js +1 -1
  37. package/dist/icon-set/mdi-v3.umd.prod.js +1 -1
  38. package/dist/icon-set/mdi-v4.umd.prod.js +1 -1
  39. package/dist/icon-set/mdi-v5.umd.prod.js +1 -1
  40. package/dist/icon-set/mdi-v6.umd.prod.js +1 -1
  41. package/dist/icon-set/svg-bootstrap-icons.umd.prod.js +1 -1
  42. package/dist/icon-set/svg-eva-icons.umd.prod.js +1 -1
  43. package/dist/icon-set/svg-fontawesome-v5.umd.prod.js +1 -1
  44. package/dist/icon-set/svg-ionicons-v4.umd.prod.js +1 -1
  45. package/dist/icon-set/svg-ionicons-v5.umd.prod.js +1 -1
  46. package/dist/icon-set/svg-ionicons-v6.umd.prod.js +1 -1
  47. package/dist/icon-set/svg-line-awesome.umd.prod.js +1 -1
  48. package/dist/icon-set/svg-material-icons-outlined.umd.prod.js +1 -1
  49. package/dist/icon-set/svg-material-icons-round.umd.prod.js +1 -1
  50. package/dist/icon-set/svg-material-icons-sharp.umd.prod.js +1 -1
  51. package/dist/icon-set/svg-material-icons.umd.prod.js +1 -1
  52. package/dist/icon-set/svg-mdi-v4.umd.prod.js +1 -1
  53. package/dist/icon-set/svg-mdi-v5.umd.prod.js +1 -1
  54. package/dist/icon-set/svg-mdi-v6.umd.prod.js +1 -1
  55. package/dist/icon-set/svg-themify.umd.prod.js +1 -1
  56. package/dist/icon-set/themify.umd.prod.js +1 -1
  57. package/dist/lang/ar.umd.prod.js +1 -1
  58. package/dist/lang/az-Latn.umd.prod.js +1 -1
  59. package/dist/lang/bg.umd.prod.js +1 -1
  60. package/dist/lang/bn.umd.prod.js +1 -1
  61. package/dist/lang/ca.umd.prod.js +1 -1
  62. package/dist/lang/cs.umd.prod.js +1 -1
  63. package/dist/lang/da.umd.prod.js +1 -1
  64. package/dist/lang/de.umd.prod.js +1 -1
  65. package/dist/lang/el.umd.prod.js +1 -1
  66. package/dist/lang/en-GB.umd.prod.js +1 -1
  67. package/dist/lang/en-US.umd.prod.js +1 -1
  68. package/dist/lang/eo.umd.prod.js +1 -1
  69. package/dist/lang/es.umd.prod.js +1 -1
  70. package/dist/lang/et.umd.prod.js +1 -1
  71. package/dist/lang/fa-IR.umd.prod.js +1 -1
  72. package/dist/lang/fa.umd.prod.js +1 -1
  73. package/dist/lang/fi.umd.prod.js +1 -1
  74. package/dist/lang/fr.umd.prod.js +1 -1
  75. package/dist/lang/gn.umd.prod.js +1 -1
  76. package/dist/lang/he.umd.prod.js +1 -1
  77. package/dist/lang/hr.umd.prod.js +1 -1
  78. package/dist/lang/hu.umd.prod.js +1 -1
  79. package/dist/lang/id.umd.prod.js +1 -1
  80. package/dist/lang/is.umd.prod.js +1 -1
  81. package/dist/lang/it.umd.prod.js +1 -1
  82. package/dist/lang/ja.umd.prod.js +1 -1
  83. package/dist/lang/km.umd.prod.js +1 -1
  84. package/dist/lang/ko-KR.umd.prod.js +1 -1
  85. package/dist/lang/kur-CKB.umd.prod.js +1 -1
  86. package/dist/lang/lt.umd.prod.js +1 -1
  87. package/dist/lang/lu.umd.prod.js +1 -1
  88. package/dist/lang/lv.umd.prod.js +1 -1
  89. package/dist/lang/ml.umd.prod.js +1 -1
  90. package/dist/lang/ms.umd.prod.js +1 -1
  91. package/dist/lang/nb-NO.umd.prod.js +1 -1
  92. package/dist/lang/nl.umd.prod.js +1 -1
  93. package/dist/lang/pl.umd.prod.js +1 -1
  94. package/dist/lang/pt-BR.umd.prod.js +1 -1
  95. package/dist/lang/pt.umd.prod.js +1 -1
  96. package/dist/lang/ro.umd.prod.js +1 -1
  97. package/dist/lang/ru.umd.prod.js +1 -1
  98. package/dist/lang/sk.umd.prod.js +1 -1
  99. package/dist/lang/sl.umd.prod.js +1 -1
  100. package/dist/lang/sr-CYR.umd.prod.js +1 -1
  101. package/dist/lang/sr.umd.prod.js +1 -1
  102. package/dist/lang/sv.umd.prod.js +1 -1
  103. package/dist/lang/ta.umd.prod.js +1 -1
  104. package/dist/lang/th.umd.prod.js +1 -1
  105. package/dist/lang/tr.umd.prod.js +1 -1
  106. package/dist/lang/ug.umd.prod.js +1 -1
  107. package/dist/lang/uk.umd.prod.js +1 -1
  108. package/dist/lang/vi.umd.prod.js +1 -1
  109. package/dist/lang/zh-CN.umd.prod.js +1 -1
  110. package/dist/lang/zh-TW.umd.prod.js +1 -1
  111. package/dist/quasar.cjs.prod.js +2 -2
  112. package/dist/quasar.css +275 -191
  113. package/dist/quasar.esm.prod.js +2 -2
  114. package/dist/quasar.prod.css +1 -1
  115. package/dist/quasar.rtl.css +347 -270
  116. package/dist/quasar.rtl.prod.css +1 -1
  117. package/dist/quasar.sass +275 -217
  118. package/dist/quasar.umd.js +16598 -16283
  119. package/dist/quasar.umd.prod.js +2 -2
  120. package/dist/ssr-directives/Morph.js +1 -1
  121. package/dist/transforms/loader-asset-urls.json +20 -0
  122. package/dist/types/api/slider.d.ts +46 -0
  123. package/dist/types/api/validation.d.ts +4 -0
  124. package/dist/types/api.d.ts +2 -0
  125. package/dist/types/composables.d.ts +3 -3
  126. package/dist/types/index.d.ts +611 -140
  127. package/dist/vetur/quasar-attributes.json +251 -83
  128. package/dist/vetur/quasar-tags.json +59 -17
  129. package/dist/web-types/web-types.json +580 -152
  130. package/package.json +1 -1
  131. package/src/api.extends.json +0 -1
  132. package/src/components/breadcrumbs/QBreadcrumbs.js +7 -2
  133. package/src/components/breadcrumbs/QBreadcrumbs.sass +0 -3
  134. package/src/components/breadcrumbs/QBreadcrumbsEl.js +14 -8
  135. package/src/components/btn/QBtn.js +5 -5
  136. package/src/components/btn/use-btn.js +21 -21
  137. package/src/components/btn/use-btn.json +22 -13
  138. package/src/components/btn-dropdown/QBtnDropdown.json +1 -0
  139. package/src/components/btn-toggle/QBtnToggle.json +3 -0
  140. package/src/components/checkbox/use-checkbox.js +1 -1
  141. package/src/components/chip/QChip.json +1 -2
  142. package/src/components/color/QColor.js +32 -26
  143. package/src/components/color/QColor.sass +10 -23
  144. package/src/components/date/QDate.sass +2 -0
  145. package/src/components/drawer/QDrawer.js +18 -15
  146. package/src/components/editor/QEditor.js +1 -1
  147. package/src/components/editor/QEditor.sass +10 -1
  148. package/src/components/expansion-item/QExpansionItem.js +4 -1
  149. package/src/components/expansion-item/QExpansionItem.json +2 -1
  150. package/src/components/fab/QFab.js +18 -12
  151. package/src/components/fab/QFab.json +36 -1
  152. package/src/components/fab/QFab.sass +1 -1
  153. package/src/components/fab/QFabAction.js +14 -7
  154. package/src/components/fab/QFabAction.json +10 -0
  155. package/src/components/file/QFile.js +12 -5
  156. package/src/components/file/QFile.json +6 -6
  157. package/src/components/file/QFile.sass +4 -2
  158. package/src/components/footer/QFooter.js +1 -1
  159. package/src/components/form/QForm.json +2 -3
  160. package/src/components/header/QHeader.js +1 -1
  161. package/src/components/icon/QIcon.js +2 -2
  162. package/src/components/infinite-scroll/QInfiniteScroll.js +4 -5
  163. package/src/components/item/QItem.js +2 -3
  164. package/src/components/linear-progress/QLinearProgress.js +3 -2
  165. package/src/components/option-group/QOptionGroup.js +3 -0
  166. package/src/components/option-group/QOptionGroup.json +48 -2
  167. package/src/components/parallax/QParallax.js +4 -2
  168. package/src/components/popup-edit/QPopupEdit.js +2 -5
  169. package/src/components/popup-proxy/QPopupProxy.json +2 -1
  170. package/src/components/radio/QRadio.js +2 -7
  171. package/src/components/range/QRange.js +103 -222
  172. package/src/components/range/QRange.json +11 -121
  173. package/src/components/rating/QRating.json +1 -1
  174. package/src/components/scroll-area/QScrollArea.js +3 -1
  175. package/src/components/scroll-area/QScrollArea.json +5 -6
  176. package/src/components/select/QSelect.js +4 -1
  177. package/src/components/select/QSelect.json +17 -4
  178. package/src/components/slider/QSlider.js +46 -132
  179. package/src/components/slider/QSlider.json +1 -121
  180. package/src/components/slider/QSlider.sass +198 -132
  181. package/src/components/slider/use-slider.js +453 -109
  182. package/src/components/slider/use-slider.json +546 -0
  183. package/src/components/stepper/QStepper.js +3 -3
  184. package/src/components/stepper/QStepper.sass +24 -26
  185. package/src/components/table/QTable.js +27 -47
  186. package/src/components/tabs/QRouteTab.js +1 -2
  187. package/src/components/tabs/QRouteTab.json +0 -7
  188. package/src/components/tabs/QTabs.js +71 -20
  189. package/src/components/tabs/use-tab.js +26 -13
  190. package/src/components/tree/QTree.js +14 -12
  191. package/src/components/tree/QTree.json +12 -12
  192. package/src/components/tree/QTree.sass +45 -41
  193. package/src/components/uploader/QUploader.json +14 -2
  194. package/src/components/uploader/uploader-core.js +16 -9
  195. package/src/components/virtual-scroll/QVirtualScroll.json +15 -0
  196. package/src/components/virtual-scroll/QVirtualScroll.sass +1 -0
  197. package/src/components/virtual-scroll/use-virtual-scroll.js +30 -17
  198. package/src/components/virtual-scroll/use-virtual-scroll.json +2 -5
  199. package/src/composables/private/use-field.js +5 -5
  200. package/src/composables/private/use-file.js +20 -5
  201. package/src/composables/private/use-form.js +2 -3
  202. package/src/composables/private/use-fullscreen.js +15 -4
  203. package/src/composables/private/use-router-link.js +44 -23
  204. package/src/composables/private/use-router-link.json +26 -10
  205. package/src/composables/private/use-split-attrs.js +4 -4
  206. package/src/composables/private/use-validate.js +21 -15
  207. package/src/composables/private/use-validate.json +1 -0
  208. package/src/css/core/helpers.sass +3 -0
  209. package/src/css/core/positioning.sass +5 -0
  210. package/src/css/variables.sass +4 -6
  211. package/src/directives/ScrollFire.js +1 -0
  212. package/src/icon-set.js +2 -4
  213. package/src/plugins/AppFullscreen.js +70 -53
  214. package/src/plugins/AppVisibility.js +2 -3
  215. package/src/plugins/BottomSheet.js +3 -5
  216. package/src/plugins/Dialog.js +3 -5
  217. package/src/plugins/Dialog.json +2 -3
  218. package/src/plugins/LoadingBar.js +17 -18
  219. package/src/plugins/Notify.js +296 -295
  220. package/src/plugins/Platform.js +14 -14
  221. package/src/utils/date.js +4 -4
  222. package/src/utils/dom.js +2 -2
  223. package/src/utils/open-url.js +2 -2
  224. package/src/utils/patterns.js +1 -0
  225. package/src/utils/private/define-reactive-plugin.js +10 -8
  226. package/src/utils/private/global-dialog.js +6 -8
  227. package/src/utils/private/inject-obj-prop.js +13 -0
  228. package/src/utils/private/is.js +2 -2
@@ -23,6 +23,7 @@ import { useTableRowSelection, useTableRowSelectionProps, useTableRowSelectionEm
23
23
  import { useTableRowExpand, useTableRowExpandProps, useTableRowExpandEmits } from './table-row-expand.js'
24
24
  import { useTableColumnSelection, useTableColumnSelectionProps } from './table-column-selection.js'
25
25
 
26
+ import { injectProp, injectMultipleProps } from '../../utils/private/inject-obj-prop.js'
26
27
  import { createComponent } from '../../utils/private/create.js'
27
28
 
28
29
  const bottomClass = 'q-table__bottom row items-center'
@@ -477,11 +478,7 @@ export default createComponent({
477
478
 
478
479
  data.cols = data.cols.map(col => {
479
480
  const c = { ...col }
480
- Object.defineProperty(c, 'value', {
481
- get: () => getCellValue(col, data.row),
482
- configurable: true,
483
- enumerable: true
484
- })
481
+ injectProp(c, 'value', () => getCellValue(col, data.row))
485
482
  return c
486
483
  })
487
484
 
@@ -490,13 +487,7 @@ export default createComponent({
490
487
 
491
488
  function getBodyCellScope (data) {
492
489
  injectBodyCommonScope(data)
493
-
494
- Object.defineProperty(data, 'value', {
495
- get: () => getCellValue(data.col, data.row),
496
- configurable: true,
497
- enumerable: true
498
- })
499
-
490
+ injectProp(data, 'value', () => getCellValue(data.col, data.row))
500
491
  return data
501
492
  }
502
493
 
@@ -516,23 +507,21 @@ export default createComponent({
516
507
  dense: props.dense
517
508
  })
518
509
 
519
- hasSelectionMode.value === true && Object.defineProperty(data, 'selected', {
520
- get: () => isRowSelected(data.key),
521
- set: (adding, evt) => {
510
+ hasSelectionMode.value === true && injectProp(
511
+ data,
512
+ 'selected',
513
+ () => isRowSelected(data.key),
514
+ (adding, evt) => {
522
515
  updateSelection([ data.key ], [ data.row ], adding, evt)
523
- },
524
- configurable: true,
525
- enumerable: true
526
- })
516
+ }
517
+ )
527
518
 
528
- Object.defineProperty(data, 'expand', {
529
- get: () => isRowExpanded(data.key),
530
- set: adding => {
531
- updateExpanded(data.key, adding)
532
- },
533
- configurable: true,
534
- enumerable: true
535
- })
519
+ injectProp(
520
+ data,
521
+ 'expand',
522
+ () => isRowExpanded(data.key),
523
+ adding => { updateExpanded(data.key, adding) }
524
+ )
536
525
  }
537
526
 
538
527
  function getCellValue (col, row) {
@@ -562,7 +551,7 @@ export default createComponent({
562
551
  topSelection = slots[ 'top-selection' ],
563
552
  hasSelection = hasSelectionMode.value === true
564
553
  && topSelection !== void 0
565
- && rowsSelectedNumber.vaue > 0,
554
+ && rowsSelectedNumber.value > 0,
566
555
  topClass = 'q-table__top relative-position row items-center'
567
556
 
568
557
  if (top !== void 0) {
@@ -704,12 +693,12 @@ export default createComponent({
704
693
  })
705
694
 
706
695
  if (multipleSelection.value === true) {
707
- Object.defineProperty(data, 'selected', {
708
- get: () => headerSelectedValue.value,
709
- set: onMultipleSelectionSet,
710
- configurable: true,
711
- enumerable: true
712
- })
696
+ injectProp(
697
+ data,
698
+ 'selected',
699
+ () => headerSelectedValue.value,
700
+ onMultipleSelectionSet
701
+ )
713
702
  }
714
703
 
715
704
  return data
@@ -1024,19 +1013,10 @@ export default createComponent({
1024
1013
  getCellValue
1025
1014
  })
1026
1015
 
1027
- Object.defineProperty(vm.proxy, 'filteredSortedRows', {
1028
- get: () => filteredSortedRows.value,
1029
- enumerable: true
1030
- })
1031
-
1032
- Object.defineProperty(vm.proxy, 'computedRows', {
1033
- get: () => computedRows.value,
1034
- enumerable: true
1035
- })
1036
-
1037
- Object.defineProperty(vm.proxy, 'computedRowsNumber', {
1038
- get: () => computedRowsNumber.value,
1039
- enumerable: true
1016
+ injectMultipleProps(vm.proxy, {
1017
+ filteredSortedRows: () => filteredSortedRows.value,
1018
+ computedRows: () => computedRows.value,
1019
+ computedRowsNumber: () => computedRowsNumber.value
1040
1020
  })
1041
1021
 
1042
1022
  return () => {
@@ -10,8 +10,7 @@ export default createComponent({
10
10
 
11
11
  props: {
12
12
  ...useRouterLinkProps,
13
- ...useTabProps,
14
- to: { required: true }
13
+ ...useTabProps
15
14
  },
16
15
 
17
16
  emits: useTabEmits,
@@ -5,13 +5,6 @@
5
5
 
6
6
  "mixins": [ "components/tabs/QTab", "composables/private/use-router-link" ],
7
7
 
8
- "props": {
9
- "to": {
10
- "required": true,
11
- "category": "general"
12
- }
13
- },
14
-
15
8
  "events": {
16
9
  "click": {
17
10
  "desc": "Emitted when component is clicked (activated)",
@@ -87,6 +87,7 @@ export default createComponent({
87
87
  )
88
88
 
89
89
  const tabList = []
90
+ const hasFocus = ref(false)
90
91
 
91
92
  let localFromRoute = false, animateTimer, scrollTimer, unwatchRoute
92
93
  let localUpdateArrows = arrowsEnabled.value === true
@@ -126,7 +127,7 @@ export default createComponent({
126
127
  )
127
128
 
128
129
  const innerClass = computed(() =>
129
- 'q-tabs__content row no-wrap items-center self-stretch hide-scrollbar '
130
+ 'q-tabs__content row no-wrap items-center self-stretch hide-scrollbar relative-position '
130
131
  + alignClass.value
131
132
  + (props.contentClass !== void 0 ? ` ${ props.contentClass }` : '')
132
133
  + ($q.platform.is.mobile === true ? ' scroll' : '')
@@ -201,7 +202,7 @@ export default createComponent({
201
202
  contentRef.value[ domProps.value.scroll ],
202
203
  Array.prototype.reduce.call(
203
204
  contentRef.value.children,
204
- (acc, el) => acc + el[ domProps.value.content ],
205
+ (acc, el) => acc + (el[ domProps.value.content ] || 0),
205
206
  0
206
207
  )
207
208
  ),
@@ -260,23 +261,27 @@ export default createComponent({
260
261
  }
261
262
 
262
263
  if (newTab && scrollable.value === true) {
263
- const
264
- { left, width, top, height } = contentRef.value.getBoundingClientRect(),
265
- newPos = newTab.rootRef.value.getBoundingClientRect()
264
+ scrollToTabEl(newTab.rootRef.value)
265
+ }
266
+ }
266
267
 
267
- let offset = props.vertical === true ? newPos.top - top : newPos.left - left
268
+ function scrollToTabEl (el) {
269
+ const
270
+ { left, width, top, height } = contentRef.value.getBoundingClientRect(),
271
+ newPos = el.getBoundingClientRect()
268
272
 
269
- if (offset < 0) {
270
- contentRef.value[ props.vertical === true ? 'scrollTop' : 'scrollLeft' ] += Math.floor(offset)
271
- localUpdateArrows()
272
- return
273
- }
273
+ let offset = props.vertical === true ? newPos.top - top : newPos.left - left
274
274
 
275
- offset += props.vertical === true ? newPos.height - height : newPos.width - width
276
- if (offset > 0) {
277
- contentRef.value[ props.vertical === true ? 'scrollTop' : 'scrollLeft' ] += Math.ceil(offset)
278
- localUpdateArrows()
279
- }
275
+ if (offset < 0) {
276
+ contentRef.value[ props.vertical === true ? 'scrollTop' : 'scrollLeft' ] += Math.floor(offset)
277
+ localUpdateArrows()
278
+ return
279
+ }
280
+
281
+ offset += props.vertical === true ? newPos.height - height : newPos.width - width
282
+ if (offset > 0) {
283
+ contentRef.value[ props.vertical === true ? 'scrollTop' : 'scrollLeft' ] += Math.ceil(offset)
284
+ localUpdateArrows()
280
285
  }
281
286
  }
282
287
 
@@ -312,17 +317,56 @@ export default createComponent({
312
317
  }
313
318
 
314
319
  function scrollToStart () {
315
- animScrollTo(rtlPosCorrection.value === true ? 9999 : 0)
320
+ animScrollTo(rtlPosCorrection.value === true ? Number.MAX_SAFE_INTEGER : 0)
316
321
  }
317
322
 
318
323
  function scrollToEnd () {
319
- animScrollTo(rtlPosCorrection.value === true ? 0 : 9999)
324
+ animScrollTo(rtlPosCorrection.value === true ? 0 : Number.MAX_SAFE_INTEGER)
320
325
  }
321
326
 
322
327
  function stopAnimScroll () {
323
328
  clearInterval(scrollTimer)
324
329
  }
325
330
 
331
+ function onKbdNavigate (keyCode, fromEl) {
332
+ const tabs = Array.prototype.filter.call(
333
+ contentRef.value.children,
334
+ el => el === fromEl || (el.matches && el.matches('.q-tab.q-focusable') === true)
335
+ )
336
+
337
+ const len = tabs.length
338
+ if (len === 0) { return }
339
+
340
+ if (keyCode === 36) { // Home
341
+ scrollToTabEl(tabs[ 0 ])
342
+ return true
343
+ }
344
+ if (keyCode === 35) { // End
345
+ scrollToTabEl(tabs[ len - 1 ])
346
+ return true
347
+ }
348
+
349
+ const dirPrev = (props.vertical === true && keyCode === 38 /* ArrowUp */)
350
+ || (props.vertical !== true && keyCode === 37 /* ArrowLeft */)
351
+
352
+ const dirNext = (props.vertical === true && keyCode === 40 /* ArrowDown */)
353
+ || (props.vertical !== true && keyCode === 39 /* ArrowRight */)
354
+
355
+ const dir = dirPrev === true ? -1 : (dirNext === true ? 1 : void 0)
356
+
357
+ if (dir !== void 0) {
358
+ const rtlDir = isRTL.value === true ? -1 : 1
359
+ const index = tabs.indexOf(fromEl) + dir * rtlDir
360
+
361
+ if (index >= 0 && index < len) {
362
+ scrollToTabEl(tabs[ index ])
363
+ tabs[ index ].focus({ preventScroll: true })
364
+ }
365
+
366
+ return true
367
+ }
368
+ }
369
+
326
370
  // let's speed up execution of time-sensitive scrollTowards()
327
371
  // with a computed variable by directly applying the minimal
328
372
  // number of instructions on get/set functions
@@ -368,7 +412,7 @@ export default createComponent({
368
412
  }
369
413
 
370
414
  function getRouteList () {
371
- return tabList.filter(tab => tab.routerProps !== void 0 && tab.routerProps.hasLink.value === true)
415
+ return tabList.filter(tab => tab.routerProps !== void 0 && tab.routerProps.hasRouterLink.value === true)
372
416
  }
373
417
 
374
418
  // do not use directly; use verifyRouteModel() instead
@@ -440,6 +484,9 @@ export default createComponent({
440
484
  }
441
485
  }
442
486
 
487
+ function onFocusin () { hasFocus.value = true }
488
+ function onFocusout () { hasFocus.value = false }
489
+
443
490
  function verifyRouteModel () {
444
491
  if ($tabs.avoidRouteWatcher !== true) {
445
492
  registerTimeout(updateActiveRoute)
@@ -485,6 +532,7 @@ export default createComponent({
485
532
  const $tabs = {
486
533
  currentModel,
487
534
  tabProps,
535
+ hasFocus,
488
536
 
489
537
  registerTab,
490
538
  unregisterTab,
@@ -492,6 +540,7 @@ export default createComponent({
492
540
  verifyRouteModel,
493
541
  updateModel,
494
542
  recalculateScroll,
543
+ onKbdNavigate,
495
544
 
496
545
  avoidRouteWatcher: false
497
546
  }
@@ -543,7 +592,9 @@ export default createComponent({
543
592
  return h('div', {
544
593
  ref: rootRef,
545
594
  class: classes.value,
546
- role: 'tablist'
595
+ role: 'tablist',
596
+ onFocusin,
597
+ onFocusout
547
598
  }, child)
548
599
  }
549
600
  }
@@ -1,16 +1,17 @@
1
- import { h, ref, computed, inject, onBeforeUnmount, onMounted, withDirectives } from 'vue'
1
+ import { h, ref, computed, inject, onBeforeUnmount, onMounted, withDirectives, getCurrentInstance } from 'vue'
2
2
 
3
3
  import QIcon from '../icon/QIcon.js'
4
4
 
5
5
  import Ripple from '../../directives/Ripple.js'
6
6
 
7
7
  import { hMergeSlot } from '../../utils/private/render.js'
8
- import { isKeyCode } from '../../utils/private/key-composition.js'
8
+ import { isKeyCode, shouldIgnoreKey } from '../../utils/private/key-composition.js'
9
9
  import { tabsKey } from '../../utils/private/symbols.js'
10
+ import { stopAndPrevent } from '../../utils/event.js'
10
11
 
11
12
  let uid = 0
12
13
 
13
- export const useTabEmits = [ 'click', 'keyup' ]
14
+ export const useTabEmits = [ 'click', 'keydown' ]
14
15
 
15
16
  export const useTabProps = {
16
17
  icon: String,
@@ -42,14 +43,19 @@ export default function (props, slots, emit, routerProps) {
42
43
  console.error('QTab/QRouteTab component needs to be child of QTabs')
43
44
  })
44
45
 
46
+ const { proxy } = getCurrentInstance()
47
+
45
48
  const blurTargetRef = ref(null)
46
49
  const rootRef = ref(null)
47
50
  const tabIndicatorRef = ref(null)
48
51
 
49
52
  const ripple = computed(() => (
50
- props.disable === true
53
+ props.disable === true || props.ripple === false
51
54
  ? false
52
- : props.ripple
55
+ : Object.assign(
56
+ { keyCodes: [ 13, 32 ], early: true },
57
+ props.ripple === true ? {} : props.ripple
58
+ )
53
59
  ))
54
60
 
55
61
  const isActive = computed(() => $tabs.currentModel.value === props.name)
@@ -79,7 +85,9 @@ export default function (props, slots, emit, routerProps) {
79
85
  )
80
86
 
81
87
  const tabIndex = computed(() => (
82
- props.disable === true || isActive.value === true ? -1 : props.tabindex || 0
88
+ props.disable === true || $tabs.hasFocus.value === true
89
+ ? -1
90
+ : props.tabindex || 0
83
91
  ))
84
92
 
85
93
  function onClick (e, keyboard) {
@@ -89,12 +97,12 @@ export default function (props, slots, emit, routerProps) {
89
97
  let go
90
98
 
91
99
  if (routerProps !== void 0) {
92
- if (routerProps.hasLink.value === true) {
100
+ if (routerProps.hasRouterLink.value === true) {
93
101
  go = () => {
94
102
  e.__qNavigate = true
95
103
  $tabs.avoidRouteWatcher = true
96
104
 
97
- const res = routerProps.navigateToLink(e)
105
+ const res = routerProps.navigateToRouterLink(e)
98
106
 
99
107
  if (res === false) {
100
108
  $tabs.avoidRouteWatcher = false
@@ -123,9 +131,14 @@ export default function (props, slots, emit, routerProps) {
123
131
  }
124
132
  }
125
133
 
126
- function onKeyup (e) {
127
- isKeyCode(e, 13) === true && onClick(e, true)
128
- emit('keyup', e)
134
+ function onKeydown (e) {
135
+ if (isKeyCode(e, [ 13, 32 ])) {
136
+ onClick(e, true)
137
+ }
138
+ else if (shouldIgnoreKey(e) !== true && e.keyCode >= 35 && e.keyCode <= 40) {
139
+ $tabs.onKbdNavigate(e.keyCode, proxy.$el) === true && stopAndPrevent(e)
140
+ }
141
+ emit('keydown', e)
129
142
  }
130
143
 
131
144
  function getContent () {
@@ -201,10 +214,10 @@ export default function (props, slots, emit, routerProps) {
201
214
  class: classes.value,
202
215
  tabindex: tabIndex.value,
203
216
  role: 'tab',
204
- 'aria-selected': isActive.value,
217
+ 'aria-selected': isActive.value === true ? 'true' : 'false',
205
218
  'aria-disabled': props.disable === true ? 'true' : void 0,
206
219
  onClick,
207
- onKeyup,
220
+ onKeydown,
208
221
  ...customData
209
222
  }
210
223
 
@@ -13,6 +13,7 @@ import useDark, { useDarkProps } from '../../composables/private/use-dark.js'
13
13
  import { createComponent } from '../../utils/private/create.js'
14
14
  import { stopAndPrevent } from '../../utils/event.js'
15
15
  import { shouldIgnoreKey } from '../../utils/private/key-composition.js'
16
+ import { injectProp } from '../../utils/private/inject-obj-prop.js'
16
17
 
17
18
  const tickStrategyOptions = [ 'none', 'strict', 'leaf', 'leaf-filtered' ]
18
19
 
@@ -431,18 +432,19 @@ export default createComponent({
431
432
  function getSlotScope (node, meta, key) {
432
433
  const scope = { tree: proxy, node, key, color: props.color, dark: isDark.value }
433
434
 
434
- Object.defineProperty(scope, 'expanded', {
435
- get: () => { return meta.expanded },
436
- set: val => { val !== meta.expanded && setExpanded(key, val) },
437
- configurable: true,
438
- enumerable: true
439
- })
440
- Object.defineProperty(scope, 'ticked', {
441
- get: () => { return meta.ticked },
442
- set: val => { val !== meta.ticked && setTicked([ key ], val) },
443
- configurable: true,
444
- enumerable: true
445
- })
435
+ injectProp(
436
+ scope,
437
+ 'expanded',
438
+ () => { return meta.expanded },
439
+ val => { val !== meta.expanded && setExpanded(key, val) }
440
+ )
441
+
442
+ injectProp(
443
+ scope,
444
+ 'ticked',
445
+ () => { return meta.ticked },
446
+ val => { val !== meta.ticked && setTicked([ key ], val) }
447
+ )
446
448
 
447
449
  return scope
448
450
  }
@@ -186,9 +186,9 @@
186
186
  "reactive": true
187
187
  },
188
188
  "tree": {
189
- "type": "Object",
190
- "desc": "QTree instance",
191
- "__exemption": [ "examples" ]
189
+ "type": "Component",
190
+ "tsType": "QTree",
191
+ "desc": "QTree instance"
192
192
  },
193
193
  "node": {
194
194
  "type": "Object",
@@ -226,9 +226,9 @@
226
226
  "reactive": true
227
227
  },
228
228
  "tree": {
229
- "type": "Object",
230
- "desc": "QTree instance",
231
- "__exemption": [ "examples" ]
229
+ "type": "Component",
230
+ "tsType": "QTree",
231
+ "desc": "QTree instance"
232
232
  },
233
233
  "node": {
234
234
  "type": "Object",
@@ -266,9 +266,9 @@
266
266
  "reactive": true
267
267
  },
268
268
  "tree": {
269
- "type": "Object",
270
- "desc": "QTree instance",
271
- "__exemption": [ "examples" ]
269
+ "type": "Component",
270
+ "tsType": "QTree",
271
+ "desc": "QTree instance"
272
272
  },
273
273
  "node": {
274
274
  "type": "Object",
@@ -306,9 +306,9 @@
306
306
  "reactive": true
307
307
  },
308
308
  "tree": {
309
- "type": "Object",
310
- "desc": "QTree instance",
311
- "__exemption": [ "examples" ]
309
+ "type": "Component",
310
+ "tsType": "QTree",
311
+ "desc": "QTree instance"
312
312
  },
313
313
  "node": {
314
314
  "type": "Object",
@@ -130,47 +130,51 @@
130
130
  .q-tree__node-body:after
131
131
  display: none !important
132
132
 
133
- &--dense .q-tree
134
- &__arrow,
135
- &__spinner
136
- margin-right: 1px
137
-
138
- &__img
139
- height: 32px
140
-
141
- &__tickbox
142
- margin-right: 3px
143
-
144
- &__node
145
- padding: 0
146
- &:after
147
- top: 0
148
- left: -8px
149
-
150
- &__node-header
151
- margin-top: 0
152
- padding: 1px
153
- &:before
154
- top: 0
155
- left: -8px
156
- width: 8px
157
-
158
- &__node--child
159
- padding-left: 17px
160
- > .q-tree__node-header:before
161
- left: -25px
162
- width: 21px
163
-
164
- &__node-body
165
- padding: 0 0 2px
166
-
167
- &__node--parent > .q-tree__node-collapsible > .q-tree__node-body
168
- padding: 0 0 2px 20px
169
- &:after
170
- left: 8px
171
-
172
- &__children
173
- padding-left: 16px
133
+ &--dense
134
+ > .q-tree__node--child > .q-tree__node-header
135
+ padding-left: 1px
136
+
137
+ .q-tree
138
+ &__arrow,
139
+ &__spinner
140
+ margin-right: 1px
141
+
142
+ &__img
143
+ height: 32px
144
+
145
+ &__tickbox
146
+ margin-right: 3px
147
+
148
+ &__node
149
+ padding: 0
150
+ &:after
151
+ top: 0
152
+ left: -8px
153
+
154
+ &__node-header
155
+ margin-top: 0
156
+ padding: 1px
157
+ &:before
158
+ top: 0
159
+ left: -8px
160
+ width: 8px
161
+
162
+ &__node--child
163
+ padding-left: 17px
164
+ > .q-tree__node-header:before
165
+ left: -25px
166
+ width: 21px
167
+
168
+ &__node-body
169
+ padding: 0 0 2px
170
+
171
+ &__node--parent > .q-tree__node-collapsible > .q-tree__node-body
172
+ padding: 0 0 2px 20px
173
+ &:after
174
+ left: 8px
175
+
176
+ &__children
177
+ padding-left: 16px
174
178
 
175
179
  [dir=rtl]
176
180
  .q-tree__arrow
@@ -67,12 +67,24 @@
67
67
  "slots": {
68
68
  "header": {
69
69
  "desc": "Slot for custom header; Scope is the QUploader instance itself",
70
- "__exemption": ["scope"]
70
+ "scope": {
71
+ "...self": {
72
+ "type": "Component",
73
+ "tsType": "QUploader",
74
+ "desc": "QUploader instance"
75
+ }
76
+ }
71
77
  },
72
78
 
73
79
  "list": {
74
80
  "desc": "Slot for custom list; Scope is the QUploader instance itself",
75
- "__exemption": ["scope"]
81
+ "scope": {
82
+ "...self": {
83
+ "type": "Component",
84
+ "tsType": "QUploader",
85
+ "desc": "QUploader instance"
86
+ }
87
+ }
76
88
  }
77
89
  },
78
90