quasar 2.4.8 → 2.4.12

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 (147) hide show
  1. package/dist/api/LoadingBar.json +7 -0
  2. package/dist/api/Platform.json +171 -0
  3. package/dist/api/QAjaxBar.json +13 -1
  4. package/dist/api/QFile.json +1 -0
  5. package/dist/api/QTree.json +7 -0
  6. package/dist/api/QUploader.json +3 -1
  7. package/dist/icon-set/bootstrap-icons.umd.prod.js +1 -1
  8. package/dist/icon-set/eva-icons.umd.prod.js +1 -1
  9. package/dist/icon-set/fontawesome-v5-pro.umd.prod.js +1 -1
  10. package/dist/icon-set/fontawesome-v5.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/mdi-v3.umd.prod.js +1 -1
  18. package/dist/icon-set/mdi-v4.umd.prod.js +1 -1
  19. package/dist/icon-set/mdi-v5.umd.prod.js +1 -1
  20. package/dist/icon-set/mdi-v6.umd.prod.js +1 -1
  21. package/dist/icon-set/svg-bootstrap-icons.umd.prod.js +1 -1
  22. package/dist/icon-set/svg-eva-icons.umd.prod.js +1 -1
  23. package/dist/icon-set/svg-fontawesome-v5.umd.prod.js +1 -1
  24. package/dist/icon-set/svg-ionicons-v4.umd.prod.js +1 -1
  25. package/dist/icon-set/svg-ionicons-v5.umd.prod.js +1 -1
  26. package/dist/icon-set/svg-ionicons-v6.umd.prod.js +1 -1
  27. package/dist/icon-set/svg-line-awesome.umd.prod.js +1 -1
  28. package/dist/icon-set/svg-material-icons-outlined.umd.prod.js +1 -1
  29. package/dist/icon-set/svg-material-icons-round.umd.prod.js +1 -1
  30. package/dist/icon-set/svg-material-icons-sharp.umd.prod.js +1 -1
  31. package/dist/icon-set/svg-material-icons.umd.prod.js +1 -1
  32. package/dist/icon-set/svg-mdi-v4.umd.prod.js +1 -1
  33. package/dist/icon-set/svg-mdi-v5.umd.prod.js +1 -1
  34. package/dist/icon-set/svg-mdi-v6.umd.prod.js +1 -1
  35. package/dist/icon-set/svg-themify.umd.prod.js +1 -1
  36. package/dist/icon-set/themify.umd.prod.js +1 -1
  37. package/dist/lang/ar.umd.prod.js +1 -1
  38. package/dist/lang/az-Latn.umd.prod.js +1 -1
  39. package/dist/lang/bg.umd.prod.js +1 -1
  40. package/dist/lang/bn.umd.prod.js +1 -1
  41. package/dist/lang/ca.umd.prod.js +1 -1
  42. package/dist/lang/cs.umd.prod.js +1 -1
  43. package/dist/lang/da.umd.prod.js +1 -1
  44. package/dist/lang/de.umd.prod.js +1 -1
  45. package/dist/lang/el.umd.prod.js +1 -1
  46. package/dist/lang/en-GB.umd.prod.js +1 -1
  47. package/dist/lang/en-US.umd.prod.js +1 -1
  48. package/dist/lang/eo.umd.prod.js +1 -1
  49. package/dist/lang/es.umd.prod.js +1 -1
  50. package/dist/lang/et.umd.prod.js +1 -1
  51. package/dist/lang/fa-IR.umd.prod.js +1 -1
  52. package/dist/lang/fa.umd.prod.js +1 -1
  53. package/dist/lang/fi.umd.prod.js +1 -1
  54. package/dist/lang/fr.umd.prod.js +1 -1
  55. package/dist/lang/gn.umd.prod.js +1 -1
  56. package/dist/lang/he.umd.prod.js +1 -1
  57. package/dist/lang/hr.umd.prod.js +1 -1
  58. package/dist/lang/hu.umd.prod.js +1 -1
  59. package/dist/lang/id.umd.prod.js +1 -1
  60. package/dist/lang/is.umd.prod.js +1 -1
  61. package/dist/lang/it.umd.prod.js +1 -1
  62. package/dist/lang/ja.umd.prod.js +1 -1
  63. package/dist/lang/km.umd.prod.js +1 -1
  64. package/dist/lang/ko-KR.umd.prod.js +1 -1
  65. package/dist/lang/kur-CKB.umd.prod.js +1 -1
  66. package/dist/lang/lt.umd.prod.js +1 -1
  67. package/dist/lang/lu.umd.prod.js +1 -1
  68. package/dist/lang/lv.umd.prod.js +1 -1
  69. package/dist/lang/ml.umd.prod.js +1 -1
  70. package/dist/lang/ms.umd.prod.js +1 -1
  71. package/dist/lang/my.umd.prod.js +6 -0
  72. package/dist/lang/nb-NO.umd.prod.js +1 -1
  73. package/dist/lang/nl.umd.prod.js +1 -1
  74. package/dist/lang/pl.umd.prod.js +1 -1
  75. package/dist/lang/pt-BR.umd.prod.js +1 -1
  76. package/dist/lang/pt.umd.prod.js +1 -1
  77. package/dist/lang/ro.umd.prod.js +1 -1
  78. package/dist/lang/ru.umd.prod.js +1 -1
  79. package/dist/lang/sk.umd.prod.js +1 -1
  80. package/dist/lang/sl.umd.prod.js +1 -1
  81. package/dist/lang/sr-CYR.umd.prod.js +1 -1
  82. package/dist/lang/sr.umd.prod.js +1 -1
  83. package/dist/lang/sv.umd.prod.js +1 -1
  84. package/dist/lang/ta.umd.prod.js +1 -1
  85. package/dist/lang/th.umd.prod.js +1 -1
  86. package/dist/lang/tr.umd.prod.js +1 -1
  87. package/dist/lang/ug.umd.prod.js +1 -1
  88. package/dist/lang/uk.umd.prod.js +1 -1
  89. package/dist/lang/vi.umd.prod.js +1 -1
  90. package/dist/lang/zh-CN.umd.prod.js +1 -1
  91. package/dist/lang/zh-TW.umd.prod.js +1 -1
  92. package/dist/quasar.cjs.prod.js +2 -2
  93. package/dist/quasar.css +10 -3
  94. package/dist/quasar.esm.prod.js +2 -2
  95. package/dist/quasar.prod.css +1 -1
  96. package/dist/quasar.rtl.css +10 -3
  97. package/dist/quasar.rtl.prod.css +1 -1
  98. package/dist/quasar.sass +9 -3
  99. package/dist/quasar.umd.js +207 -101
  100. package/dist/quasar.umd.prod.js +2 -2
  101. package/dist/ssr-directives/Morph.js +1 -1
  102. package/dist/types/api/qfile.d.ts +8 -0
  103. package/dist/types/api/qselect.d.ts +4 -0
  104. package/dist/types/api/qtable.d.ts +12 -0
  105. package/dist/types/api/qtree.d.ts +31 -0
  106. package/dist/types/api/quploader.d.ts +28 -0
  107. package/dist/types/api/touchswipe.d.ts +11 -0
  108. package/dist/types/api/validation.d.ts +1 -1
  109. package/dist/types/api.d.ts +6 -0
  110. package/dist/types/index.d.ts +422 -314
  111. package/dist/types/ts-helpers.d.ts +6 -2
  112. package/dist/types/utils.d.ts +4 -1
  113. package/dist/vetur/quasar-attributes.json +4 -0
  114. package/dist/vetur/quasar-tags.json +1 -0
  115. package/dist/web-types/web-types.json +11 -1
  116. package/lang/index.json +4 -0
  117. package/lang/my.js +90 -0
  118. package/package.json +1 -1
  119. package/src/components/ajax-bar/QAjaxBar.js +22 -12
  120. package/src/components/ajax-bar/QAjaxBar.json +16 -1
  121. package/src/components/date/QDate.js +6 -1
  122. package/src/components/dialog/QDialog.js +1 -1
  123. package/src/components/dialog-plugin/DialogPlugin.js +1 -1
  124. package/src/components/editor/QEditor.js +1 -1
  125. package/src/components/form/QForm.js +12 -2
  126. package/src/components/icon/QIcon.js +3 -3
  127. package/src/components/icon/QIcon.sass +2 -2
  128. package/src/components/infinite-scroll/QInfiniteScroll.js +3 -2
  129. package/src/components/input/QInput.js +1 -1
  130. package/src/components/menu/QMenu.js +2 -1
  131. package/src/components/scroll-area/QScrollArea.js +36 -11
  132. package/src/components/select/QSelect.js +32 -27
  133. package/src/components/select/QSelect.sass +4 -0
  134. package/src/components/stepper/QStep.js +19 -14
  135. package/src/components/stepper/QStepper.sass +3 -0
  136. package/src/components/tabs/QTabs.js +10 -2
  137. package/src/components/tree/QTree.js +8 -1
  138. package/src/components/tree/QTree.json +8 -0
  139. package/src/components/uploader/uploader-core.js +2 -0
  140. package/src/components/uploader/xhr-uploader-plugin.json +2 -1
  141. package/src/components/virtual-scroll/use-virtual-scroll.js +14 -5
  142. package/src/composables/private/use-field.js +18 -9
  143. package/src/composables/private/use-file.json +1 -0
  144. package/src/plugins/LoadingBar.js +3 -3
  145. package/src/plugins/LoadingBar.json +8 -0
  146. package/src/plugins/Platform.js +15 -8
  147. package/src/plugins/Platform.json +166 -0
@@ -610,8 +610,12 @@ export default createComponent({
610
610
  return innerOptionsValue.value.find(v => isDeepEqual(v, val)) !== void 0
611
611
  }
612
612
 
613
- function selectInputText () {
614
- if (props.useInput === true && targetRef.value !== null) {
613
+ function selectInputText (e) {
614
+ if (
615
+ props.useInput === true
616
+ && targetRef.value !== null
617
+ && (e === void 0 || (targetRef.value === e.target && e.target.value === selectedString.value))
618
+ ) {
615
619
  targetRef.value.select()
616
620
  }
617
621
  }
@@ -644,34 +648,34 @@ export default createComponent({
644
648
 
645
649
  if (typeof value === 'string' && value.length > 0) {
646
650
  const needle = value.toLocaleLowerCase()
651
+ const findFn = extractFn => {
652
+ const option = props.options.find(opt => extractFn.value(opt).toLocaleLowerCase() === needle)
647
653
 
648
- let fn = opt => getOptionValue.value(opt).toLocaleLowerCase() === needle
649
- let option = props.options.find(fn)
654
+ if (option === void 0) {
655
+ return false
656
+ }
650
657
 
651
- if (option !== void 0) {
652
658
  if (innerValue.value.indexOf(option) === -1) {
653
659
  toggleOption(option)
654
660
  }
655
661
  else {
656
662
  hidePopup()
657
663
  }
658
- }
659
- else {
660
- fn = opt => getOptionLabel.value(opt).toLocaleLowerCase() === needle
661
- option = props.options.find(fn)
662
664
 
663
- if (option !== void 0) {
664
- if (innerValue.value.indexOf(option) === -1) {
665
- toggleOption(option)
666
- }
667
- else {
668
- hidePopup()
669
- }
665
+ return true
666
+ }
667
+ const fillFn = afterFilter => {
668
+ if (findFn(getOptionValue) === true) {
669
+ return
670
670
  }
671
- else {
672
- filter(value, true)
671
+ if (findFn(getOptionLabel) === true || afterFilter === true) {
672
+ return
673
673
  }
674
+
675
+ filter(value, true, () => fillFn(true))
674
676
  }
677
+
678
+ fillFn()
675
679
  }
676
680
  else {
677
681
  state.clearValue(e)
@@ -981,7 +985,7 @@ export default createComponent({
981
985
  type: 'search',
982
986
  ...comboboxAttrs.value,
983
987
  ...state.splitAttrs.attributes.value,
984
- id: state.targetUid.value,
988
+ id: isTarget === true ? state.targetUid.value : void 0,
985
989
  maxlength: props.maxlength,
986
990
  autocomplete: props.autocomplete,
987
991
  'data-autofocus': (fromDialog !== true && props.autofocus === true) || void 0,
@@ -992,7 +996,7 @@ export default createComponent({
992
996
 
993
997
  if (fromDialog !== true && hasDialog === true) {
994
998
  if (Array.isArray(data.class) === true) {
995
- data.class[ 0 ] += ' no-pointer-events'
999
+ data.class = [ ...data.class, 'no-pointer-events' ]
996
1000
  }
997
1001
  else {
998
1002
  data.class += ' no-pointer-events'
@@ -1050,7 +1054,7 @@ export default createComponent({
1050
1054
  }
1051
1055
  }
1052
1056
 
1053
- function filter (val, keepClosed) {
1057
+ function filter (val, keepClosed, afterUpdateFn) {
1054
1058
  if (props.onFilter === void 0 || (keepClosed !== true && state.focused.value !== true)) {
1055
1059
  return
1056
1060
  }
@@ -1108,6 +1112,7 @@ export default createComponent({
1108
1112
  }
1109
1113
 
1110
1114
  typeof afterFn === 'function' && nextTick(() => { afterFn(proxy) })
1115
+ typeof afterUpdateFn === 'function' && nextTick(() => { afterUpdateFn(proxy) })
1111
1116
  })
1112
1117
  }
1113
1118
  },
@@ -1457,13 +1462,13 @@ export default createComponent({
1457
1462
  child.push(getInput(fromDialog, isTarget))
1458
1463
  }
1459
1464
  // there can be only one (when dialog is opened the control in dialog should be target)
1460
- else if (state.editable.value === true && isTarget === true) {
1465
+ else if (state.editable.value === true) {
1461
1466
  child.push(
1462
1467
  h('div', {
1463
- ref: targetRef,
1468
+ ref: isTarget === true ? targetRef : void 0,
1464
1469
  key: 'd_t',
1465
- class: 'no-outline',
1466
- id: state.targetUid.value,
1470
+ class: 'q-select__focus-target',
1471
+ id: isTarget === true ? state.targetUid.value : void 0,
1467
1472
  ...comboboxAttrs.value,
1468
1473
  onKeydown: onTargetKeydown,
1469
1474
  onKeyup: onTargetKeyup,
@@ -1471,10 +1476,10 @@ export default createComponent({
1471
1476
  })
1472
1477
  )
1473
1478
 
1474
- if (typeof props.autocomplete === 'string' && props.autocomplete.length > 0) {
1479
+ if (isTarget === true && typeof props.autocomplete === 'string' && props.autocomplete.length > 0) {
1475
1480
  child.push(
1476
1481
  h('input', {
1477
- class: 'q-select__autocomplete-input no-outline',
1482
+ class: 'q-select__autocomplete-input',
1478
1483
  autocomplete: props.autocomplete,
1479
1484
  onKeyup: onTargetAutocomplete
1480
1485
  })
@@ -8,11 +8,15 @@
8
8
 
9
9
  .q-field__input
10
10
  min-width: 50px !important
11
+ cursor: text
11
12
 
12
13
  &--padding
13
14
  padding-left: 4px
14
15
 
16
+ &__focus-target,
15
17
  &__autocomplete-input
18
+ position: absolute
19
+ outline: 0 !important
16
20
  width: 0
17
21
  height: 0
18
22
  padding: 0
@@ -1,4 +1,4 @@
1
- import { h, ref, computed, watch, nextTick, inject, KeepAlive } from 'vue'
1
+ import { h, ref, computed, inject, getCurrentInstance, KeepAlive } from 'vue'
2
2
 
3
3
  import QSlideTransition from '../slide-transition/QSlideTransition.js'
4
4
  import StepHeader from './StepHeader.js'
@@ -56,7 +56,9 @@ export default createComponent({
56
56
  error: Boolean
57
57
  },
58
58
 
59
- setup (props, { slots }) {
59
+ setup (props, { attrs, slots }) {
60
+ const { proxy: { $q } } = getCurrentInstance()
61
+
60
62
  const $stepper = inject(stepperKey, () => {
61
63
  console.error('QStep needs to be child of QStepper')
62
64
  })
@@ -67,18 +69,21 @@ export default createComponent({
67
69
 
68
70
  const isActive = computed(() => $stepper.value.modelValue === props.name)
69
71
 
70
- watch(isActive, active => {
71
- if (
72
- active === true
73
- && $stepper.value.vertical === true
74
- ) {
75
- nextTick(() => {
76
- if (rootRef.value !== null) {
77
- rootRef.value.scrollTop = 0
72
+ const scrollEvent = computed(() => (
73
+ ($q.platform.is.ios !== true && $q.platform.is.safari !== true)
74
+ || isActive.value !== true
75
+ || $stepper.value.vertical !== true
76
+ ? {}
77
+ : {
78
+ onScroll (e) {
79
+ const { target } = e
80
+ if (target.scrollTop > 0) {
81
+ target.scrollTop = 0
82
+ }
83
+ attrs.onScroll !== void 0 && attrs.onScroll(e)
78
84
  }
79
- })
80
- }
81
- })
85
+ }
86
+ ))
82
87
 
83
88
  const contentKey = computed(() => (
84
89
  typeof props.name === 'string' || typeof props.name === 'number'
@@ -114,7 +119,7 @@ export default createComponent({
114
119
 
115
120
  return () => h(
116
121
  'div',
117
- { ref: rootRef, class: 'q-stepper__step' },
122
+ { ref: rootRef, class: 'q-stepper__step', ...scrollEvent.value },
118
123
  $stepper.value.vertical === true
119
124
  ? [
120
125
  h(StepHeader, {
@@ -13,6 +13,7 @@
13
13
  line-height: 14px
14
14
 
15
15
  &__dot
16
+ contain: layout
16
17
  margin-right: 8px
17
18
  font-size: 14px
18
19
  width: 24px
@@ -20,6 +21,7 @@
20
21
  height: 24px
21
22
  border-radius: 50%
22
23
  background: currentColor
24
+
23
25
  span
24
26
  color: #fff
25
27
 
@@ -133,6 +135,7 @@
133
135
  .q-stepper__tab
134
136
  overflow: hidden
135
137
  .q-stepper__line
138
+ contain: layout
136
139
  &:before, &:after
137
140
  position: absolute
138
141
  top: 50%
@@ -1,4 +1,4 @@
1
- import { h, ref, computed, watch, nextTick, onBeforeUnmount, onActivated, getCurrentInstance, provide } from 'vue'
1
+ import { h, ref, computed, watch, nextTick, onBeforeUnmount, onActivated, onDeactivated, getCurrentInstance, provide } from 'vue'
2
2
 
3
3
  import QIcon from '../icon/QIcon.js'
4
4
  import QResizeObserver from '../resize-observer/QResizeObserver.js'
@@ -568,7 +568,15 @@ export default createComponent({
568
568
  unwatchRoute !== void 0 && unwatchRoute()
569
569
  })
570
570
 
571
- onActivated(recalculateScroll)
571
+ let shouldActivate = false
572
+
573
+ onDeactivated(() => {
574
+ shouldActivate = true
575
+ })
576
+
577
+ onActivated(() => {
578
+ shouldActivate === true && recalculateScroll()
579
+ })
572
580
 
573
581
  return () => {
574
582
  const child = [
@@ -58,6 +58,8 @@ export default createComponent({
58
58
  expanded: Array, // v-model:expanded
59
59
  selected: {}, // v-model:selected
60
60
 
61
+ noSelectionUnset: Boolean,
62
+
61
63
  defaultExpandAll: Boolean,
62
64
  accordion: Boolean,
63
65
 
@@ -615,7 +617,12 @@ export default createComponent({
615
617
 
616
618
  if (hasSelection.value) {
617
619
  if (meta.selectable) {
618
- emit('update:selected', meta.key !== props.selected ? meta.key : null)
620
+ if (props.noSelectionUnset === false) {
621
+ emit('update:selected', meta.key !== props.selected ? meta.key : null)
622
+ }
623
+ else if (meta.key !== props.selected) {
624
+ emit('update:selected', meta.key || null)
625
+ }
619
626
  }
620
627
  }
621
628
  else {
@@ -6,6 +6,7 @@
6
6
  "props": {
7
7
  "nodes": {
8
8
  "type": "Array",
9
+ "tsType": "QTreeNode",
9
10
  "desc": "The array of nodes that designates the tree structure",
10
11
  "required": true,
11
12
  "examples": [ "[ {...}, {...} ]" ],
@@ -106,6 +107,13 @@
106
107
  "category": "state"
107
108
  },
108
109
 
110
+ "no-selection-unset": {
111
+ "type": "Boolean",
112
+ "desc": "Do not allow un-selection when clicking currently selected node",
113
+ "category": "behavior",
114
+ "addedIn": "v2.4.10"
115
+ },
116
+
109
117
  "default-expand-all": {
110
118
  "type": "Boolean",
111
119
  "desc": "Allow the tree to have all its branches expanded, when first rendered",
@@ -436,6 +436,8 @@ export function getRenderer (getPlugin) {
436
436
  abort: state.abort
437
437
  }
438
438
 
439
+ // TODO: the result of this computed, especially the dynamic part, isn't currently typed
440
+ // This result in an error with Volar when accessing the state (eg. files array)
439
441
  const slotScope = computed(() => {
440
442
  const acc = {
441
443
  canAddFiles: canAddFiles.value,
@@ -2,6 +2,7 @@
2
2
  "props": {
3
3
  "factory": {
4
4
  "type": "Function",
5
+ "tsType": "QUploaderFactoryFn",
5
6
  "desc": "Function which should return an Object or a Promise resolving with an Object; For best performance, reference it from your scope and do not define it inline",
6
7
  "params": {
7
8
  "files": {
@@ -112,7 +113,7 @@
112
113
  },
113
114
  "returns": {
114
115
  "type": "String",
115
- "desc": "An array consists of objects with header definitions",
116
+ "desc": "An array consisting of objects with header definitions",
116
117
  "__exemption": [ "examples" ]
117
118
  },
118
119
  "category": "upload"
@@ -1,4 +1,4 @@
1
- import { h, ref, computed, watch, onActivated, onBeforeMount, onBeforeUnmount, nextTick, getCurrentInstance } from 'vue'
1
+ import { h, ref, computed, watch, onActivated, onDeactivated, onBeforeMount, onBeforeUnmount, nextTick, getCurrentInstance } from 'vue'
2
2
 
3
3
  import debounce from '../../utils/debounce.js'
4
4
  import { noop } from '../../utils/event.js'
@@ -559,13 +559,14 @@ export function useVirtualScroll ({
559
559
  prevToIndex = -1
560
560
  prevScrollStart = void 0
561
561
 
562
+ virtualScrollPaddingBefore.value = sumSize(virtualScrollSizesAgg, virtualScrollSizes, 0, virtualScrollSliceRange.value.from)
563
+ virtualScrollPaddingAfter.value = sumSize(virtualScrollSizesAgg, virtualScrollSizes, virtualScrollSliceRange.value.to, virtualScrollLength.value)
564
+
562
565
  if (toIndex >= 0) {
563
566
  updateVirtualScrollSizes(virtualScrollSliceRange.value.from)
564
567
  nextTick(() => { scrollTo(toIndex) })
565
568
  }
566
569
  else {
567
- virtualScrollPaddingBefore.value = sumSize(virtualScrollSizesAgg, virtualScrollSizes, 0, virtualScrollSliceRange.value.from)
568
- virtualScrollPaddingAfter.value = sumSize(virtualScrollSizesAgg, virtualScrollSizes, virtualScrollSliceRange.value.to, virtualScrollLength.value)
569
570
  onVirtualScrollEvt()
570
571
  }
571
572
  }
@@ -596,9 +597,9 @@ export function useVirtualScroll ({
596
597
  : Math.ceil(scrollViewSize / virtualScrollItemSizeComputed.value)
597
598
 
598
599
  const baseSize = Math.max(
599
- 10,
600
+ 1,
600
601
  view,
601
- Math.ceil(props.virtualScrollSliceSize / multiplier)
602
+ Math.ceil((props.virtualScrollSliceSize > 0 ? props.virtualScrollSliceSize : 10) / multiplier)
602
603
  )
603
604
 
604
605
  virtualScrollSliceSizeComputed.value = {
@@ -691,7 +692,15 @@ export function useVirtualScroll ({
691
692
  setVirtualScrollSize()
692
693
  })
693
694
 
695
+ let shouldActivate = false
696
+
697
+ onDeactivated(() => {
698
+ shouldActivate = true
699
+ })
700
+
694
701
  onActivated(() => {
702
+ if (shouldActivate !== true) { return }
703
+
695
704
  const scrollEl = getVirtualScrollTarget()
696
705
 
697
706
  if (prevScrollStart !== void 0 && scrollEl !== void 0 && scrollEl !== null && scrollEl.nodeType !== 8) {
@@ -1,4 +1,4 @@
1
- import { h, ref, computed, watch, Transition, nextTick, onBeforeUnmount, onMounted, getCurrentInstance } from 'vue'
1
+ import { h, ref, computed, watch, Transition, nextTick, onActivated, onDeactivated, onBeforeUnmount, onMounted, getCurrentInstance } from 'vue'
2
2
 
3
3
  import { isRuntimeSsrPreHydration } from '../../plugins/Platform.js'
4
4
 
@@ -270,7 +270,7 @@ export default function (state) {
270
270
  if (target && (el === null || el.id !== state.targetUid.value)) {
271
271
  target.hasAttribute('tabindex') === true || (target = target.querySelector('[tabindex]'))
272
272
  if (target && target !== el) {
273
- target.focus()
273
+ target.focus({ preventScroll: true })
274
274
  }
275
275
  }
276
276
  }
@@ -288,6 +288,7 @@ export default function (state) {
288
288
  }
289
289
 
290
290
  function onControlFocusin (e) {
291
+ clearTimeout(focusoutTimer)
291
292
  if (state.editable.value === true && state.focused.value === false) {
292
293
  state.focused.value = true
293
294
  emit('focus', e)
@@ -300,13 +301,9 @@ export default function (state) {
300
301
  if (
301
302
  document.hasFocus() === true && (
302
303
  state.hasPopupOpen === true
303
- || (
304
- state.controlRef !== void 0
305
- && (
306
- state.controlRef.value === null
307
- || state.controlRef.value.contains(document.activeElement) !== false
308
- )
309
- )
304
+ || state.controlRef === void 0
305
+ || state.controlRef.value === null
306
+ || state.controlRef.value.contains(document.activeElement) !== false
310
307
  )
311
308
  ) {
312
309
  return
@@ -402,6 +399,8 @@ export default function (state) {
402
399
  name: props.clearIcon || $q.iconSet.field.clear,
403
400
  tabindex: 0,
404
401
  type: 'button',
402
+ 'aria-hidden': null,
403
+ role: null,
405
404
  onClick: clearValue
406
405
  })
407
406
  ])
@@ -530,6 +529,16 @@ export default function (state) {
530
529
  // expose public methods
531
530
  Object.assign(proxy, { focus, blur })
532
531
 
532
+ let shouldActivate = false
533
+
534
+ onDeactivated(() => {
535
+ shouldActivate = true
536
+ })
537
+
538
+ onActivated(() => {
539
+ shouldActivate === true && props.autofocus === true && proxy.focus()
540
+ })
541
+
533
542
  onMounted(() => {
534
543
  if (isRuntimeSsrPreHydration.value === true && props.for === void 0) {
535
544
  state.targetUid.value = getTargetUid()
@@ -72,6 +72,7 @@
72
72
  "params": {
73
73
  "rejectedEntries": {
74
74
  "type": "Array",
75
+ "tsType": "QRejectedEntry",
75
76
  "desc": "Array of { failedPropValidation: string, file: File } Objects for files that do not pass the validation",
76
77
  "__exemption": ["examples"]
77
78
  }
@@ -49,11 +49,11 @@ const Plugin = defineReactivePlugin({
49
49
  Object.assign(this, {
50
50
  start (speed) {
51
51
  barRef.value.start(speed)
52
- Plugin.isActive = barRef.value.calls > 0
52
+ Plugin.isActive = true
53
53
  },
54
54
  stop () {
55
- barRef.value.stop()
56
- Plugin.isActive = barRef.value.calls > 0
55
+ const sessions = barRef.value.stop()
56
+ Plugin.isActive = sessions > 0
57
57
  },
58
58
  increment () {
59
59
  barRef.value.increment.apply(null, arguments)
@@ -16,6 +16,14 @@
16
16
  }
17
17
  },
18
18
 
19
+ "props": {
20
+ "isActive": {
21
+ "type": "Boolean",
22
+ "desc": "Is LoadingBar active?",
23
+ "reactive": true
24
+ }
25
+ },
26
+
19
27
  "methods": {
20
28
  "start": {
21
29
  "desc": "Notify bar you've started a background activity",
@@ -1,6 +1,4 @@
1
1
  /* eslint-disable no-useless-escape */
2
- /* eslint-disable no-unused-expressions */
3
- /* eslint-disable no-mixed-operators */
4
2
 
5
3
  import { ref, reactive } from 'vue'
6
4
  import { injectProp } from '../utils/private/inject-obj-prop'
@@ -25,19 +23,15 @@ export let iosEmulated = false
25
23
  export let iosCorrection
26
24
 
27
25
  function getMatch (userAgent, platformMatch) {
28
- const match = /(edge|edga|edgios)\/([\w.]+)/.exec(userAgent)
26
+ const match = /(edg|edge|edga|edgios)\/([\w.]+)/.exec(userAgent)
29
27
  || /(opr)[\/]([\w.]+)/.exec(userAgent)
30
28
  || /(vivaldi)[\/]([\w.]+)/.exec(userAgent)
31
29
  || /(chrome|crios)[\/]([\w.]+)/.exec(userAgent)
32
- || /(iemobile)[\/]([\w.]+)/.exec(userAgent)
33
30
  || /(version)(applewebkit)[\/]([\w.]+).*(safari)[\/]([\w.]+)/.exec(userAgent)
34
31
  || /(webkit)[\/]([\w.]+).*(version)[\/]([\w.]+).*(safari)[\/]([\w.]+)/.exec(userAgent)
35
32
  || /(firefox|fxios)[\/]([\w.]+)/.exec(userAgent)
36
33
  || /(webkit)[\/]([\w.]+)/.exec(userAgent)
37
34
  || /(opera)(?:.*version|)[\/]([\w.]+)/.exec(userAgent)
38
- || /(msie) ([\w.]+)/.exec(userAgent)
39
- || (userAgent.indexOf('trident') >= 0 && /(rv)(?::| )([\w.]+)/.exec(userAgent))
40
- || (userAgent.indexOf('compatible') < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(userAgent))
41
35
  || []
42
36
 
43
37
  return {
@@ -60,6 +54,8 @@ function getPlatformMatch (userAgent) {
60
54
  || /(mac)/.exec(userAgent)
61
55
  || /(linux)/.exec(userAgent)
62
56
  || /(cros)/.exec(userAgent)
57
+ // TODO: Remove BlackBerry detection. BlackBerry OS, BlackBerry 10, and BlackBerry PlayBook OS
58
+ // is officially dead as of January 4, 2022 (https://www.blackberry.com/us/en/support/devices/end-of-life)
63
59
  || /(playbook)/.exec(userAgent)
64
60
  || /(bb)/.exec(userAgent)
65
61
  || /(blackberry)/.exec(userAgent)
@@ -151,6 +147,10 @@ function getPlatform (UA) {
151
147
  delete browser[ 'windows phone' ]
152
148
  }
153
149
 
150
+ // TODO: The assumption about WebKit based browsers below is not completely accurate.
151
+ // Google released Blink(a fork of WebKit) engine on April 3, 2013, which is really different than WebKit today.
152
+ // Today, one might want to check for WebKit to deal with its bugs, which is used on all browsers on iOS, and Safari browser on all platforms.
153
+
154
154
  // Chrome, Opera 15+, Vivaldi and Safari are webkit based browsers
155
155
  if (
156
156
  browser.chrome
@@ -167,8 +167,15 @@ function getPlatform (UA) {
167
167
  browser.webkit = true
168
168
  }
169
169
 
170
+ // TODO: (Qv3) rename the terms 'edge' to 'edge legacy'(or remove it) then 'edge chromium' to 'edge' to match with the known up-to-date terms
171
+ // Microsoft Edge is the new Chromium-based browser. Microsoft Edge Legacy is the old EdgeHTML-based browser (EOL: March 9, 2021).
172
+ if (browser.edg) {
173
+ matched.browser = 'edgechromium'
174
+ browser.edgeChromium = true
175
+ }
176
+
170
177
  // Blackberry browsers are marked as Safari on BlackBerry
171
- if (browser.safari && browser.blackberry || browser.bb) {
178
+ if ((browser.safari && browser.blackberry) || browser.bb) {
172
179
  matched.browser = 'blackberry'
173
180
  browser.blackberry = true
174
181
  }