quasar 2.8.4 → 2.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/dist/api/QBreadcrumbsEl.json +52 -0
  2. package/dist/api/QBtn.json +41 -6
  3. package/dist/api/QBtnDropdown.json +1 -1
  4. package/dist/api/QChip.json +1 -1
  5. package/dist/api/QEditor.json +7 -0
  6. package/dist/api/QExpansionItem.json +1 -1
  7. package/dist/api/QItem.json +52 -0
  8. package/dist/api/QRating.json +13 -0
  9. package/dist/api/QRouteTab.json +42 -6
  10. package/dist/icon-set/bootstrap-icons.umd.prod.js +1 -1
  11. package/dist/icon-set/eva-icons.umd.prod.js +1 -1
  12. package/dist/icon-set/fontawesome-v5-pro.umd.prod.js +1 -1
  13. package/dist/icon-set/fontawesome-v5.umd.prod.js +1 -1
  14. package/dist/icon-set/fontawesome-v6-pro.umd.prod.js +1 -1
  15. package/dist/icon-set/fontawesome-v6.umd.prod.js +1 -1
  16. package/dist/icon-set/ionicons-v4.umd.prod.js +1 -1
  17. package/dist/icon-set/line-awesome.umd.prod.js +1 -1
  18. package/dist/icon-set/material-icons-outlined.umd.prod.js +1 -1
  19. package/dist/icon-set/material-icons-round.umd.prod.js +1 -1
  20. package/dist/icon-set/material-icons-sharp.umd.prod.js +1 -1
  21. package/dist/icon-set/material-icons.umd.prod.js +1 -1
  22. package/dist/icon-set/material-symbols-outlined.umd.prod.js +1 -1
  23. package/dist/icon-set/material-symbols-rounded.umd.prod.js +1 -1
  24. package/dist/icon-set/material-symbols-sharp.umd.prod.js +1 -1
  25. package/dist/icon-set/mdi-v3.umd.prod.js +1 -1
  26. package/dist/icon-set/mdi-v4.umd.prod.js +1 -1
  27. package/dist/icon-set/mdi-v5.umd.prod.js +1 -1
  28. package/dist/icon-set/mdi-v6.umd.prod.js +1 -1
  29. package/dist/icon-set/svg-bootstrap-icons.umd.prod.js +1 -1
  30. package/dist/icon-set/svg-eva-icons.umd.prod.js +1 -1
  31. package/dist/icon-set/svg-fontawesome-v5.umd.prod.js +1 -1
  32. package/dist/icon-set/svg-fontawesome-v6.umd.prod.js +1 -1
  33. package/dist/icon-set/svg-ionicons-v4.umd.prod.js +1 -1
  34. package/dist/icon-set/svg-ionicons-v5.umd.prod.js +1 -1
  35. package/dist/icon-set/svg-ionicons-v6.umd.prod.js +1 -1
  36. package/dist/icon-set/svg-line-awesome.umd.prod.js +1 -1
  37. package/dist/icon-set/svg-material-icons-outlined.umd.prod.js +1 -1
  38. package/dist/icon-set/svg-material-icons-round.umd.prod.js +1 -1
  39. package/dist/icon-set/svg-material-icons-sharp.umd.prod.js +1 -1
  40. package/dist/icon-set/svg-material-icons.umd.prod.js +1 -1
  41. package/dist/icon-set/svg-material-symbols-outlined.umd.prod.js +1 -1
  42. package/dist/icon-set/svg-material-symbols-rounded.umd.prod.js +1 -1
  43. package/dist/icon-set/svg-material-symbols-sharp.umd.prod.js +1 -1
  44. package/dist/icon-set/svg-mdi-v6.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/ca.umd.prod.js +1 -1
  53. package/dist/lang/cs.umd.prod.js +1 -1
  54. package/dist/lang/da.umd.prod.js +1 -1
  55. package/dist/lang/de.umd.prod.js +1 -1
  56. package/dist/lang/el.umd.prod.js +1 -1
  57. package/dist/lang/en-GB.umd.prod.js +1 -1
  58. package/dist/lang/en-US.umd.prod.js +1 -1
  59. package/dist/lang/eo.umd.prod.js +1 -1
  60. package/dist/lang/es.umd.prod.js +1 -1
  61. package/dist/lang/et.umd.prod.js +1 -1
  62. package/dist/lang/eu.umd.prod.js +1 -1
  63. package/dist/lang/fa-IR.umd.prod.js +1 -1
  64. package/dist/lang/fa.umd.prod.js +1 -1
  65. package/dist/lang/fi.umd.prod.js +1 -1
  66. package/dist/lang/fr.umd.prod.js +1 -1
  67. package/dist/lang/gn.umd.prod.js +1 -1
  68. package/dist/lang/he.umd.prod.js +1 -1
  69. package/dist/lang/hr.umd.prod.js +1 -1
  70. package/dist/lang/hu.umd.prod.js +1 -1
  71. package/dist/lang/id.umd.prod.js +1 -1
  72. package/dist/lang/is.umd.prod.js +1 -1
  73. package/dist/lang/it.umd.prod.js +1 -1
  74. package/dist/lang/ja.umd.prod.js +1 -1
  75. package/dist/lang/km.umd.prod.js +1 -1
  76. package/dist/lang/ko-KR.umd.prod.js +1 -1
  77. package/dist/lang/kur-CKB.umd.prod.js +1 -1
  78. package/dist/lang/kz.umd.prod.js +1 -1
  79. package/dist/lang/lt.umd.prod.js +1 -1
  80. package/dist/lang/lu.umd.prod.js +1 -1
  81. package/dist/lang/lv.umd.prod.js +1 -1
  82. package/dist/lang/ml.umd.prod.js +1 -1
  83. package/dist/lang/mm.umd.prod.js +1 -1
  84. package/dist/lang/ms.umd.prod.js +1 -1
  85. package/dist/lang/my.umd.prod.js +1 -1
  86. package/dist/lang/nb-NO.umd.prod.js +1 -1
  87. package/dist/lang/nl.umd.prod.js +2 -2
  88. package/dist/lang/pl.umd.prod.js +1 -1
  89. package/dist/lang/pt-BR.umd.prod.js +1 -1
  90. package/dist/lang/pt.umd.prod.js +1 -1
  91. package/dist/lang/ro.umd.prod.js +1 -1
  92. package/dist/lang/ru.umd.prod.js +1 -1
  93. package/dist/lang/sk.umd.prod.js +1 -1
  94. package/dist/lang/sl.umd.prod.js +1 -1
  95. package/dist/lang/sm.umd.prod.js +1 -1
  96. package/dist/lang/sr-CYR.umd.prod.js +1 -1
  97. package/dist/lang/sr.umd.prod.js +1 -1
  98. package/dist/lang/sv.umd.prod.js +1 -1
  99. package/dist/lang/ta.umd.prod.js +1 -1
  100. package/dist/lang/th.umd.prod.js +1 -1
  101. package/dist/lang/tr.umd.prod.js +1 -1
  102. package/dist/lang/ug.umd.prod.js +1 -1
  103. package/dist/lang/uk.umd.prod.js +1 -1
  104. package/dist/lang/uz-Cyrl.umd.prod.js +1 -1
  105. package/dist/lang/uz-Latn.umd.prod.js +1 -1
  106. package/dist/lang/vi.umd.prod.js +1 -1
  107. package/dist/lang/zh-CN.umd.prod.js +1 -1
  108. package/dist/lang/zh-TW.umd.prod.js +1 -1
  109. package/dist/quasar.cjs.prod.js +2 -2
  110. package/dist/quasar.esm.js +533 -337
  111. package/dist/quasar.esm.prod.js +2 -2
  112. package/dist/quasar.sass +1 -1
  113. package/dist/quasar.umd.js +532 -336
  114. package/dist/quasar.umd.prod.js +2 -2
  115. package/dist/transforms/auto-import.json +7 -3
  116. package/dist/transforms/import-map.json +2 -0
  117. package/dist/types/api/qeditor.d.ts +17 -0
  118. package/dist/types/api.d.ts +1 -0
  119. package/dist/types/index.d.ts +93 -8
  120. package/dist/types/utils/run-sequential-promises.d.ts +1 -1
  121. package/dist/vetur/quasar-attributes.json +4 -0
  122. package/dist/vetur/quasar-tags.json +1 -0
  123. package/dist/web-types/web-types.json +60 -9
  124. package/lang/nl.js +2 -2
  125. package/lang/nl.mjs +2 -2
  126. package/package.json +5 -3
  127. package/src/components/banner/__tests__/QBanner.spec.js +107 -0
  128. package/src/components/bar/__tests__/QBar.spec.js +46 -0
  129. package/src/components/breadcrumbs/QBreadcrumbsEl.js +6 -7
  130. package/src/components/breadcrumbs/QBreadcrumbsEl.json +53 -0
  131. package/src/components/btn/QBtn.js +19 -19
  132. package/src/components/btn/QBtn.json +41 -6
  133. package/src/components/btn/use-btn.js +6 -4
  134. package/src/components/btn-dropdown/QBtnDropdown.json +1 -1
  135. package/src/components/checkbox/QCheckbox.js +1 -2
  136. package/src/components/checkbox/use-checkbox.js +2 -1
  137. package/src/components/chip/QChip.json +1 -1
  138. package/src/components/dialog/QDialog.js +6 -4
  139. package/src/components/drawer/QDrawer.js +7 -4
  140. package/src/components/editor/QEditor.json +9 -0
  141. package/src/components/expansion-item/QExpansionItem.json +1 -1
  142. package/src/components/item/QItem.js +4 -5
  143. package/src/components/item/QItem.json +53 -0
  144. package/src/components/menu/QMenu.js +4 -5
  145. package/src/components/menu/__tests__/QMenu.spec.js +7 -0
  146. package/src/components/popup-edit/QPopupEdit.js +2 -5
  147. package/src/components/radio/QRadio.js +3 -3
  148. package/src/components/rating/QRating.js +48 -10
  149. package/src/components/rating/QRating.json +11 -0
  150. package/src/components/stepper/QStep.js +5 -3
  151. package/src/components/table/QTable.js +3 -5
  152. package/src/components/tabs/QRouteTab.js +6 -4
  153. package/src/components/tabs/QRouteTab.json +42 -6
  154. package/src/components/tabs/QTabs.js +188 -108
  155. package/src/components/tabs/use-tab.js +62 -38
  156. package/src/components/tooltip/QTooltip.js +7 -13
  157. package/src/components/tree/QTree.js +1 -1
  158. package/src/composables/private/__tests__/use-model-toggle.spec.js +2 -0
  159. package/src/composables/private/__tests__/use-transition.spec.js +4 -0
  160. package/src/composables/private/use-router-link.js +80 -43
  161. package/src/composables/private/use-tick.js +15 -9
  162. package/src/composables/private/use-timeout.js +20 -7
  163. package/src/directives/TouchPan.js +1 -1
  164. package/src/directives/TouchRepeat.js +1 -1
  165. package/src/directives/TouchSwipe.js +1 -1
  166. package/src/utils/extend.js +19 -19
  167. package/src/utils/private/inject-obj-prop.js +2 -0
  168. package/src/utils/private/rtl.js +10 -7
  169. package/src/utils/run-sequential-promises.js +1 -1
@@ -1,10 +1,10 @@
1
1
  /*!
2
- * Quasar Framework v2.8.4
2
+ * Quasar Framework v2.9.1
3
3
  * (c) 2015-present Razvan Stoenescu
4
4
  * Released under the MIT License.
5
5
  */
6
6
 
7
- import { ref, reactive, createApp, markRaw, defineComponent, getCurrentInstance, computed, onMounted, onBeforeUnmount, h, withDirectives, unref, Transition, nextTick, watch, onUnmounted, Teleport, KeepAlive, onBeforeMount, toRaw, provide, onDeactivated, onActivated, inject, onBeforeUpdate, shallowReactive, vShow, onUpdated, isRef, TransitionGroup } from 'vue';
7
+ import { ref, reactive, createApp, markRaw, defineComponent, getCurrentInstance, computed, onMounted, onBeforeUnmount, h, withDirectives, unref, Transition, nextTick, watch, onUnmounted, Teleport, onDeactivated, KeepAlive, onBeforeMount, toRaw, provide, onActivated, inject, onBeforeUpdate, shallowReactive, vShow, onUpdated, isRef, TransitionGroup } from 'vue';
8
8
 
9
9
  function injectProp (target, propName, get, set) {
10
10
  Object.defineProperty(target, propName, {
@@ -12,12 +12,14 @@ function injectProp (target, propName, get, set) {
12
12
  set,
13
13
  enumerable: true
14
14
  });
15
+ return target
15
16
  }
16
17
 
17
18
  function injectMultipleProps (target, props) {
18
19
  for (const key in props) {
19
20
  injectProp(target, key, props[ key ]);
20
21
  }
22
+ return target
21
23
  }
22
24
 
23
25
  /* eslint-disable no-useless-escape */
@@ -1606,7 +1608,7 @@ function prepareApp (app, uiOpts, pluginOpts) {
1606
1608
  }
1607
1609
 
1608
1610
  var installQuasar = function (parentApp, opts = {}) {
1609
- const $q = { version: '2.8.4' };
1611
+ const $q = { version: '2.9.1' };
1610
1612
 
1611
1613
  if (globalConfigIsFrozen === false) {
1612
1614
  if (opts.config !== void 0) {
@@ -2731,30 +2733,34 @@ const useRouterLinkProps = {
2731
2733
 
2732
2734
  // external props: type, tag
2733
2735
 
2734
- function useRouterLink (fallbackTag) {
2736
+ function useRouterLink ({ fallbackTag, useDisableForRouterLinkProps = true } = {}) {
2735
2737
  const vm = getCurrentInstance();
2736
- const { props, proxy } = vm;
2738
+ const { props, proxy, emit } = vm;
2737
2739
 
2738
2740
  const hasRouter = vmHasRouter(vm);
2739
2741
  const hasHrefLink = computed(() => props.disable !== true && props.href !== void 0);
2740
2742
 
2741
- const hasRouterLinkProps = computed(() =>
2742
- hasRouter === true
2743
- && props.disable !== true
2744
- && hasHrefLink.value !== true
2745
- && props.to !== void 0 && props.to !== null && props.to !== ''
2746
- );
2747
-
2748
- const linkRoute = computed(() => {
2749
- if (hasRouterLinkProps.value === true) {
2750
- try { return proxy.$router.resolve(props.to) }
2751
- catch (err) {}
2752
- }
2743
+ // for perf reasons, we use minimum amount of runtime work
2744
+ const hasRouterLinkProps = useDisableForRouterLinkProps === true
2745
+ ? computed(() =>
2746
+ hasRouter === true
2747
+ && props.disable !== true
2748
+ && hasHrefLink.value !== true
2749
+ && props.to !== void 0 && props.to !== null && props.to !== ''
2750
+ )
2751
+ : computed(() =>
2752
+ hasRouter === true
2753
+ && hasHrefLink.value !== true
2754
+ && props.to !== void 0 && props.to !== null && props.to !== ''
2755
+ );
2753
2756
 
2754
- return null
2755
- });
2757
+ const resolvedLink = computed(() => (
2758
+ hasRouterLinkProps.value === true
2759
+ ? getLink(props.to)
2760
+ : null
2761
+ ));
2756
2762
 
2757
- const hasRouterLink = computed(() => linkRoute.value !== null);
2763
+ const hasRouterLink = computed(() => resolvedLink.value !== null);
2758
2764
  const hasLink = computed(() => hasHrefLink.value === true || hasRouterLink.value === true);
2759
2765
 
2760
2766
  const linkTag = computed(() => (
@@ -2763,7 +2769,7 @@ function useRouterLink (fallbackTag) {
2763
2769
  : (props.tag || fallbackTag || 'div')
2764
2770
  ));
2765
2771
 
2766
- const linkProps = computed(() => (
2772
+ const linkAttrs = computed(() => (
2767
2773
  hasHrefLink.value === true
2768
2774
  ? {
2769
2775
  href: props.href,
@@ -2772,7 +2778,7 @@ function useRouterLink (fallbackTag) {
2772
2778
  : (
2773
2779
  hasRouterLink.value === true
2774
2780
  ? {
2775
- href: linkRoute.value.href,
2781
+ href: resolvedLink.value.href,
2776
2782
  target: props.target
2777
2783
  }
2778
2784
  : {}
@@ -2781,11 +2787,11 @@ function useRouterLink (fallbackTag) {
2781
2787
 
2782
2788
  const linkActiveIndex = computed(() => {
2783
2789
  if (hasRouterLink.value === false) {
2784
- return null
2790
+ return -1
2785
2791
  }
2786
2792
 
2787
2793
  const
2788
- { matched } = linkRoute.value,
2794
+ { matched } = resolvedLink.value,
2789
2795
  { length } = matched,
2790
2796
  routeMatched = matched[ length - 1 ];
2791
2797
 
@@ -2828,14 +2834,14 @@ function useRouterLink (fallbackTag) {
2828
2834
 
2829
2835
  const linkIsActive = computed(() =>
2830
2836
  hasRouterLink.value === true
2831
- && linkActiveIndex.value > -1
2832
- && includesParams(proxy.$route.params, linkRoute.value.params)
2837
+ && linkActiveIndex.value !== -1
2838
+ && includesParams(proxy.$route.params, resolvedLink.value.params)
2833
2839
  );
2834
2840
 
2835
2841
  const linkIsExactActive = computed(() =>
2836
2842
  linkIsActive.value === true
2837
2843
  && linkActiveIndex.value === proxy.$route.matched.length - 1
2838
- && isSameRouteLocationParams(proxy.$route.params, linkRoute.value.params)
2844
+ && isSameRouteLocationParams(proxy.$route.params, resolvedLink.value.params)
2839
2845
  );
2840
2846
 
2841
2847
  const linkClass = computed(() => (
@@ -2852,32 +2858,64 @@ function useRouterLink (fallbackTag) {
2852
2858
  : ''
2853
2859
  ));
2854
2860
 
2855
- // should match RouterLink from Vue Router
2856
- function navigateToRouterLink (e) {
2857
- if (
2858
- // component is not disabled
2859
- props.disable === true
2861
+ function getLink (to) {
2862
+ try { return proxy.$router.resolve(to) }
2863
+ catch (_) {}
2860
2864
 
2861
- // don't redirect with control keys
2862
- || e.metaKey || e.altKey || e.ctrlKey || e.shiftKey
2865
+ return null
2866
+ }
2863
2867
 
2864
- // don't redirect when preventDefault called
2865
- // ...unless calling go() from @click(e, go)
2866
- || (e.__qNavigate !== true && e.defaultPrevented === true)
2868
+ /**
2869
+ * @returns Promise<RouterError | false | undefined>
2870
+ */
2871
+ function navigateToRouterLink (
2872
+ e,
2873
+ { returnRouterError, to = props.to, replace = props.replace } = {}
2874
+ ) {
2875
+ if (props.disable === true) {
2876
+ // ensure native navigation is prevented in all cases,
2877
+ // like when useDisableForRouterLinkProps === false (QRouteTab)
2878
+ e.preventDefault();
2879
+ return Promise.resolve(false)
2880
+ }
2881
+
2882
+ if (
2883
+ // don't redirect with control keys;
2884
+ // should match RouterLink from Vue Router
2885
+ e.metaKey || e.altKey || e.ctrlKey || e.shiftKey
2867
2886
 
2868
2887
  // don't redirect on right click
2869
- || (e.button !== undefined && e.button !== 0)
2888
+ || (e.button !== void 0 && e.button !== 0)
2870
2889
 
2871
2890
  // don't redirect if it should open in a new window
2872
2891
  || props.target === '_blank'
2873
2892
  ) {
2874
- return false
2893
+ return Promise.resolve(false)
2875
2894
  }
2876
2895
 
2877
- prevent(e);
2896
+ // hinder the native navigation
2897
+ e.preventDefault();
2898
+
2899
+ // then() can also return a "soft" router error (Vue Router behavior)
2900
+ const promise = proxy.$router[ replace === true ? 'replace' : 'push' ](to);
2901
+
2902
+ return returnRouterError === true
2903
+ ? promise
2904
+ // else catching hard errors and also "soft" ones - then(err => ...)
2905
+ : promise.then(() => {}).catch(() => {})
2906
+ }
2907
+
2908
+ // warning! ensure that the component using it has 'click' included in its 'emits' definition prop
2909
+ function navigateOnClick (e) {
2910
+ if (hasRouterLink.value === true) {
2911
+ const go = opts => navigateToRouterLink(e, opts);
2878
2912
 
2879
- return proxy.$router[ props.replace === true ? 'replace' : 'push' ](props.to)
2880
- .catch(err => err)
2913
+ emit('click', e, go);
2914
+ e.defaultPrevented !== true && go();
2915
+ }
2916
+ else {
2917
+ emit('click', e);
2918
+ }
2881
2919
  }
2882
2920
 
2883
2921
  return {
@@ -2886,13 +2924,15 @@ function useRouterLink (fallbackTag) {
2886
2924
  hasLink,
2887
2925
 
2888
2926
  linkTag,
2889
- linkRoute,
2927
+ resolvedLink,
2890
2928
  linkIsActive,
2891
2929
  linkIsExactActive,
2892
2930
  linkClass,
2893
- linkProps,
2931
+ linkAttrs,
2894
2932
 
2895
- navigateToRouterLink
2933
+ getLink,
2934
+ navigateToRouterLink,
2935
+ navigateOnClick
2896
2936
  }
2897
2937
  }
2898
2938
 
@@ -2911,20 +2951,19 @@ var QBreadcrumbsEl = createComponent({
2911
2951
  }
2912
2952
  },
2913
2953
 
2954
+ emits: [ 'click' ],
2955
+
2914
2956
  setup (props, { slots }) {
2915
- const { linkTag, linkProps, linkClass, hasRouterLink, navigateToRouterLink } = useRouterLink();
2957
+ const { linkTag, linkAttrs, linkClass, navigateOnClick } = useRouterLink();
2916
2958
 
2917
2959
  const data = computed(() => {
2918
- const acc = {
2960
+ return {
2919
2961
  class: 'q-breadcrumbs__el q-link '
2920
2962
  + 'flex inline items-center relative-position '
2921
2963
  + (props.disable !== true ? 'q-link--focusable' + linkClass.value : 'q-breadcrumbs__el--disable'),
2922
- ...linkProps.value
2923
- };
2924
- if (hasRouterLink.value === true) {
2925
- acc.onClick = navigateToRouterLink;
2964
+ ...linkAttrs.value,
2965
+ onClick: navigateOnClick
2926
2966
  }
2927
- return acc
2928
2967
  });
2929
2968
 
2930
2969
  const iconClass = computed(() =>
@@ -3335,7 +3374,9 @@ const useBtnProps = {
3335
3374
  function useBtn (props) {
3336
3375
  const sizeStyle = useSize(props, defaultSizes$2);
3337
3376
  const alignClass = useAlign(props);
3338
- const { hasRouterLink, hasLink, linkTag, linkProps, navigateToRouterLink } = useRouterLink('button');
3377
+ const { hasRouterLink, hasLink, linkTag, linkAttrs, navigateOnClick } = useRouterLink({
3378
+ fallbackTag: 'button'
3379
+ });
3339
3380
 
3340
3381
  const style = computed(() => {
3341
3382
  const obj = props.fab === false && props.fabMini === false
@@ -3378,7 +3419,7 @@ function useBtn (props) {
3378
3419
  const acc = { tabindex: tabIndex.value };
3379
3420
 
3380
3421
  if (hasLink.value === true) {
3381
- Object.assign(acc, linkProps.value);
3422
+ Object.assign(acc, linkAttrs.value);
3382
3423
  }
3383
3424
  else if (formTypes.includes(props.type) === true) {
3384
3425
  acc.type = props.type;
@@ -3391,6 +3432,7 @@ function useBtn (props) {
3391
3432
  else if (acc.href === void 0) {
3392
3433
  acc.role = 'button';
3393
3434
  }
3435
+
3394
3436
  if (hasRouterLink.value !== true && mediaTypeRE.test(props.type) === true) {
3395
3437
  acc.type = props.type;
3396
3438
  }
@@ -3453,10 +3495,9 @@ function useBtn (props) {
3453
3495
  style,
3454
3496
  innerClasses,
3455
3497
  attributes,
3456
- hasRouterLink,
3457
3498
  hasLink,
3458
3499
  linkTag,
3459
- navigateToRouterLink,
3500
+ navigateOnClick,
3460
3501
  isActionable
3461
3502
  }
3462
3503
  }
@@ -3475,10 +3516,12 @@ var QBtn = createComponent({
3475
3516
  ...useBtnProps,
3476
3517
 
3477
3518
  percentage: Number,
3478
- darkPercentage: Boolean
3519
+ darkPercentage: Boolean,
3520
+
3521
+ onTouchstart: [ Function, Array ]
3479
3522
  },
3480
3523
 
3481
- emits: [ 'click', 'keydown', 'touchstart', 'mousedown', 'keyup' ],
3524
+ emits: [ 'click', 'keydown', 'mousedown', 'keyup' ],
3482
3525
 
3483
3526
  setup (props, { slots, emit }) {
3484
3527
  const { proxy } = getCurrentInstance();
@@ -3486,7 +3529,7 @@ var QBtn = createComponent({
3486
3529
  const {
3487
3530
  classes, style, innerClasses,
3488
3531
  attributes,
3489
- hasRouterLink, hasLink, linkTag, navigateToRouterLink,
3532
+ hasLink, linkTag, navigateOnClick,
3490
3533
  isActionable
3491
3534
  } = useBtn(props);
3492
3535
 
@@ -3521,7 +3564,7 @@ var QBtn = createComponent({
3521
3564
  if (props.loading === true) {
3522
3565
  return {
3523
3566
  onMousedown: onLoadingEvt,
3524
- onTouchstartPassive: onLoadingEvt,
3567
+ onTouchstart: onLoadingEvt,
3525
3568
  onClick: onLoadingEvt,
3526
3569
  onKeydown: onLoadingEvt,
3527
3570
  onKeyup: onLoadingEvt
@@ -3529,12 +3572,21 @@ var QBtn = createComponent({
3529
3572
  }
3530
3573
 
3531
3574
  if (isActionable.value === true) {
3532
- return {
3575
+ const acc = {
3533
3576
  onClick,
3534
3577
  onKeydown,
3535
- onMousedown,
3536
- onTouchstart
3578
+ onMousedown
3579
+ };
3580
+
3581
+ if (proxy.$q.platform.has.touch === true) {
3582
+ const suffix = props.onTouchstart !== void 0
3583
+ ? ''
3584
+ : 'Passive';
3585
+
3586
+ acc[ `onTouchstart${ suffix }` ] = onTouchstart;
3537
3587
  }
3588
+
3589
+ return acc
3538
3590
  }
3539
3591
 
3540
3592
  return {
@@ -3584,18 +3636,7 @@ var QBtn = createComponent({
3584
3636
  }
3585
3637
  }
3586
3638
 
3587
- if (hasRouterLink.value === true) {
3588
- const go = () => {
3589
- e.__qNavigate = true;
3590
- navigateToRouterLink(e);
3591
- };
3592
-
3593
- emit('click', e, go);
3594
- e.defaultPrevented !== true && go();
3595
- }
3596
- else {
3597
- emit('click', e);
3598
- }
3639
+ navigateOnClick(e);
3599
3640
  }
3600
3641
 
3601
3642
  function onKeydown (e) {
@@ -4539,49 +4580,64 @@ function useTransition (props, showing) {
4539
4580
  /*
4540
4581
  * Usage:
4541
4582
  * registerTick(fn)
4542
- * registerTick(fn)
4583
+ * removeTick()
4543
4584
  */
4544
4585
 
4545
4586
  function useTick () {
4546
4587
  let tickFn;
4588
+ const vm = getCurrentInstance();
4547
4589
 
4548
- onBeforeUnmount(() => {
4590
+ function removeTick () {
4549
4591
  tickFn = void 0;
4550
- });
4592
+ }
4593
+
4594
+ onDeactivated(removeTick);
4595
+ onBeforeUnmount(removeTick);
4551
4596
 
4552
4597
  return {
4598
+ removeTick,
4599
+
4553
4600
  registerTick (fn) {
4554
4601
  tickFn = fn;
4555
4602
 
4556
4603
  nextTick(() => {
4557
4604
  if (tickFn === fn) {
4558
- tickFn();
4605
+ // we also check if VM is destroyed, since if it
4606
+ // got to trigger one nextTick() we cannot stop it
4607
+ vmIsDestroyed(vm) === false && tickFn();
4559
4608
  tickFn = void 0;
4560
4609
  }
4561
4610
  });
4562
- },
4563
-
4564
- removeTick () {
4565
- tickFn = void 0;
4566
4611
  }
4567
4612
  }
4568
4613
  }
4569
4614
 
4615
+ /*
4616
+ * Usage:
4617
+ * registerTimeout(fn[, delay])
4618
+ * removeTimeout()
4619
+ */
4620
+
4570
4621
  function useTimeout () {
4571
4622
  let timer;
4623
+ const vm = getCurrentInstance();
4572
4624
 
4573
- onBeforeUnmount(() => {
4625
+ function removeTimeout () {
4574
4626
  clearTimeout(timer);
4575
- });
4627
+ }
4628
+
4629
+ onDeactivated(removeTimeout);
4630
+ onBeforeUnmount(removeTimeout);
4576
4631
 
4577
4632
  return {
4633
+ removeTimeout,
4634
+
4578
4635
  registerTimeout (fn, delay) {
4579
4636
  clearTimeout(timer);
4580
- timer = setTimeout(fn, delay);
4581
- },
4582
4637
 
4583
- removeTimeout () {
4584
- clearTimeout(timer);
4638
+ if (vmIsDestroyed(vm) === false) {
4639
+ timer = setTimeout(fn, delay);
4640
+ }
4585
4641
  }
4586
4642
  }
4587
4643
  }
@@ -5258,7 +5314,7 @@ var QMenu = createComponent({
5258
5314
 
5259
5315
  const isDark = useDark(props, $q);
5260
5316
  const { registerTick, removeTick } = useTick();
5261
- const { registerTimeout, removeTimeout } = useTimeout();
5317
+ const { registerTimeout } = useTimeout();
5262
5318
  const { transition, transitionStyle } = useTransition(props, showing);
5263
5319
  const { localScrollTarget, changeScrollEvent, unconfigureScrollTarget } = useScrollTarget(props, configureScrollTarget);
5264
5320
 
@@ -5346,9 +5402,6 @@ var QMenu = createComponent({
5346
5402
  }
5347
5403
 
5348
5404
  function handleShow (evt) {
5349
- removeTick();
5350
- removeTimeout();
5351
-
5352
5405
  refocusTarget = props.noRefocus === false
5353
5406
  ? document.activeElement
5354
5407
  : null;
@@ -5380,11 +5433,13 @@ var QMenu = createComponent({
5380
5433
  document.activeElement.blur();
5381
5434
  }
5382
5435
 
5436
+ // should removeTick() if this gets removed
5383
5437
  registerTick(() => {
5384
5438
  updatePosition();
5385
5439
  props.noFocus !== true && focus();
5386
5440
  });
5387
5441
 
5442
+ // should removeTimeout() if this gets removed
5388
5443
  registerTimeout(() => {
5389
5444
  // required in order to avoid the "double-tap needed" issue
5390
5445
  if ($q.platform.is.ios === true) {
@@ -5402,7 +5457,6 @@ var QMenu = createComponent({
5402
5457
 
5403
5458
  function handleHide (evt) {
5404
5459
  removeTick();
5405
- removeTimeout();
5406
5460
  hidePortal();
5407
5461
 
5408
5462
  anchorCleanup(true);
@@ -5420,6 +5474,7 @@ var QMenu = createComponent({
5420
5474
  refocusTarget = null;
5421
5475
  }
5422
5476
 
5477
+ // should removeTimeout() if this gets removed
5423
5478
  registerTimeout(() => {
5424
5479
  hidePortal(true); // done hiding, now destroy
5425
5480
  emit('hide', evt);
@@ -5589,7 +5644,7 @@ const randomBytes = (() => {
5589
5644
  // or improve speed by increasing this number (try 16384)
5590
5645
  const BUFFER_SIZE = 4096;
5591
5646
 
5592
- function uid$4 () {
5647
+ function uid$3 () {
5593
5648
  // Buffer some random bytes for speed
5594
5649
  if (buf === void 0 || (bufIdx + 16 > BUFFER_SIZE)) {
5595
5650
  bufIdx = 0;
@@ -5653,7 +5708,7 @@ var QBtnDropdown = createComponent({
5653
5708
 
5654
5709
  const showing = ref(props.modelValue);
5655
5710
  const menuRef = ref(null);
5656
- const targetUid = uid$4();
5711
+ const targetUid = uid$3();
5657
5712
 
5658
5713
  const attributes = computed(() => {
5659
5714
  const acc = {
@@ -6371,7 +6426,7 @@ var TouchSwipe = createDirective({
6371
6426
 
6372
6427
  client.has.touch === true && addEvt(ctx, 'main', [
6373
6428
  [ el, 'touchstart', 'touchStart', `passive${ modifiers.capture === true ? 'Capture' : '' }` ],
6374
- [ el, 'touchmove', 'noop', 'notPassiveCapture' ]
6429
+ [ el, 'touchmove', 'noop', 'notPassiveCapture' ] // cannot be passive (ex: iOS scroll)
6375
6430
  ]);
6376
6431
  },
6377
6432
 
@@ -7526,7 +7581,8 @@ function useCheckbox (type, getInner) {
7526
7581
  const child = [
7527
7582
  h('div', {
7528
7583
  class: innerClass.value,
7529
- style: sizeStyle.value
7584
+ style: sizeStyle.value,
7585
+ 'aria-hidden': 'true'
7530
7586
  }, inner)
7531
7587
  ];
7532
7588
 
@@ -7561,8 +7617,7 @@ const bgNode = h('div', {
7561
7617
  }, [
7562
7618
  h('svg', {
7563
7619
  class: 'q-checkbox__svg fit absolute-full',
7564
- viewBox: '0 0 24 24',
7565
- 'aria-hidden': 'true'
7620
+ viewBox: '0 0 24 24'
7566
7621
  }, [
7567
7622
  h('path', {
7568
7623
  class: 'q-checkbox__truthy',
@@ -8093,7 +8148,7 @@ function getChanges (evt, ctx, isFinal) {
8093
8148
  }
8094
8149
  }
8095
8150
 
8096
- let uid$3 = 0;
8151
+ let uid$2 = 0;
8097
8152
 
8098
8153
  var TouchPan = createDirective({
8099
8154
  name: 'touch-pan',
@@ -8115,7 +8170,7 @@ var TouchPan = createDirective({
8115
8170
  }
8116
8171
 
8117
8172
  const ctx = {
8118
- uid: 'qvtp_' + (uid$3++),
8173
+ uid: 'qvtp_' + (uid$2++),
8119
8174
  handler: value,
8120
8175
  modifiers,
8121
8176
  direction: getModifierDirections(modifiers),
@@ -8362,7 +8417,7 @@ var TouchPan = createDirective({
8362
8417
 
8363
8418
  client.has.touch === true && addEvt(ctx, 'main', [
8364
8419
  [ el, 'touchstart', 'touchStart', `passive${ modifiers.capture === true ? 'Capture' : '' }` ],
8365
- [ el, 'touchmove', 'noop', 'notPassiveCapture' ]
8420
+ [ el, 'touchmove', 'noop', 'notPassiveCapture' ] // cannot be passive (ex: iOS scroll)
8366
8421
  ]);
8367
8422
  },
8368
8423
 
@@ -9351,15 +9406,18 @@ let rtlHasScrollBug = false;
9351
9406
  // mobile Chrome takes the crown for this
9352
9407
  if (!__QUASAR_SSR__) {
9353
9408
  const scroller = document.createElement('div');
9354
- const spacer = document.createElement('div');
9355
-
9356
9409
  scroller.setAttribute('dir', 'rtl');
9357
- scroller.style.width = '1px';
9358
- scroller.style.height = '1px';
9359
- scroller.style.overflow = 'auto';
9410
+ Object.assign(scroller.style, {
9411
+ width: '1px',
9412
+ height: '1px',
9413
+ overflow: 'auto'
9414
+ });
9360
9415
 
9361
- spacer.style.width = '1000px';
9362
- spacer.style.height = '1px';
9416
+ const spacer = document.createElement('div');
9417
+ Object.assign(spacer.style, {
9418
+ width: '1000px',
9419
+ height: '1px'
9420
+ });
9363
9421
 
9364
9422
  document.body.appendChild(scroller);
9365
9423
  scroller.appendChild(spacer);
@@ -9379,7 +9437,6 @@ function getIndicatorClass (color, top, vertical) {
9379
9437
  }
9380
9438
 
9381
9439
  const alignValues$1 = [ 'left', 'center', 'right', 'justify' ];
9382
- const emptyFn = () => {};
9383
9440
 
9384
9441
  var QTabs = createComponent({
9385
9442
  name: 'QTabs',
@@ -9425,12 +9482,15 @@ var QTabs = createComponent({
9425
9482
  },
9426
9483
 
9427
9484
  setup (props, { slots, emit }) {
9428
- const vm = getCurrentInstance();
9429
- const { proxy: { $q } } = vm;
9485
+ const { proxy } = getCurrentInstance();
9486
+ const { $q } = proxy;
9430
9487
 
9431
9488
  const { registerTick: registerScrollTick } = useTick();
9489
+ const { registerTick: registerUpdateArrowsTick } = useTick();
9490
+ const { registerTick: registerAnimateTick } = useTick();
9491
+
9432
9492
  const { registerTimeout: registerFocusTimeout, removeTimeout: removeFocusTimeout } = useTimeout();
9433
- const { registerTimeout } = useTimeout();
9493
+ const { registerTimeout: registerScrollToTabTimeout, removeTimeout: removeScrollToTabTimeout } = useTimeout();
9434
9494
 
9435
9495
  const rootRef = ref(null);
9436
9496
  const contentRef = ref(null);
@@ -9445,10 +9505,11 @@ var QTabs = createComponent({
9445
9505
  $q.platform.is.desktop === true || props.mobileArrows === true
9446
9506
  );
9447
9507
 
9448
- const tabList = [];
9508
+ const tabDataList = [];
9509
+ const tabDataListLen = ref(0);
9449
9510
  const hasFocus = ref(false);
9450
9511
 
9451
- let localFromRoute = false, animateTimer, scrollTimer, unwatchRoute;
9512
+ let animateTimer, scrollTimer, unwatchRoute;
9452
9513
  let localUpdateArrows = arrowsEnabled.value === true
9453
9514
  ? updateArrowsFn
9454
9515
  : noop;
@@ -9467,6 +9528,19 @@ var QTabs = createComponent({
9467
9528
  noCaps: props.noCaps
9468
9529
  }));
9469
9530
 
9531
+ const hasActiveTab = computed(() => {
9532
+ const len = tabDataListLen.value;
9533
+ const val = currentModel.value;
9534
+
9535
+ for (let i = 0; i < len; i++) {
9536
+ if (tabDataList[ i ].name.value === val) {
9537
+ return true
9538
+ }
9539
+ }
9540
+
9541
+ return false
9542
+ });
9543
+
9470
9544
  const alignClass = computed(() => {
9471
9545
  const align = scrollable.value === true
9472
9546
  ? 'left'
@@ -9508,7 +9582,7 @@ var QTabs = createComponent({
9508
9582
  });
9509
9583
 
9510
9584
  watch(() => props.outsideArrows, () => {
9511
- nextTick(recalculateScroll());
9585
+ recalculateScroll();
9512
9586
  });
9513
9587
 
9514
9588
  watch(arrowsEnabled, v => {
@@ -9516,12 +9590,15 @@ var QTabs = createComponent({
9516
9590
  ? updateArrowsFn
9517
9591
  : noop;
9518
9592
 
9519
- nextTick(recalculateScroll());
9593
+ recalculateScroll();
9520
9594
  });
9521
9595
 
9522
9596
  function updateModel ({ name, setCurrent, skipEmit, fromRoute }) {
9523
9597
  if (currentModel.value !== name) {
9524
- skipEmit !== true && emit('update:modelValue', name);
9598
+ if (skipEmit !== true && props[ 'onUpdate:modelValue' ] !== void 0) {
9599
+ emit('update:modelValue', name);
9600
+ }
9601
+
9525
9602
  if (
9526
9603
  setCurrent === true
9527
9604
  || props[ 'onUpdate:modelValue' ] === void 0
@@ -9530,20 +9607,14 @@ var QTabs = createComponent({
9530
9607
  currentModel.value = name;
9531
9608
  }
9532
9609
  }
9533
-
9534
- if (fromRoute !== void 0) {
9535
- localFromRoute = fromRoute;
9536
- }
9537
9610
  }
9538
9611
 
9539
9612
  function recalculateScroll () {
9540
9613
  registerScrollTick(() => {
9541
- if (vmIsDestroyed(vm) === false) {
9542
- updateContainer({
9543
- width: rootRef.value.offsetWidth,
9544
- height: rootRef.value.offsetHeight
9545
- });
9546
- }
9614
+ updateContainer({
9615
+ width: rootRef.value.offsetWidth,
9616
+ height: rootRef.value.offsetHeight
9617
+ });
9547
9618
  });
9548
9619
  }
9549
9620
 
@@ -9565,27 +9636,21 @@ var QTabs = createComponent({
9565
9636
  ),
9566
9637
  scroll = size > 0 && scrollSize > size; // when there is no tab, in Chrome, size === 0 and scrollSize === 1
9567
9638
 
9568
- if (scrollable.value !== scroll) {
9569
- scrollable.value = scroll;
9570
- }
9639
+ scrollable.value = scroll;
9571
9640
 
9572
9641
  // Arrows need to be updated even if the scroll status was already true
9573
- scroll === true && nextTick(localUpdateArrows);
9574
-
9575
- const localJustify = size < parseInt(props.breakpoint, 10);
9642
+ scroll === true && registerUpdateArrowsTick(localUpdateArrows);
9576
9643
 
9577
- if (justify.value !== localJustify) {
9578
- justify.value = localJustify;
9579
- }
9644
+ justify.value = size < parseInt(props.breakpoint, 10);
9580
9645
  }
9581
9646
 
9582
9647
  function animate (oldName, newName) {
9583
9648
  const
9584
9649
  oldTab = oldName !== void 0 && oldName !== null && oldName !== ''
9585
- ? tabList.find(tab => tab.name.value === oldName)
9650
+ ? tabDataList.find(tab => tab.name.value === oldName)
9586
9651
  : null,
9587
9652
  newTab = newName !== void 0 && newName !== null && newName !== ''
9588
- ? tabList.find(tab => tab.name.value === newName)
9653
+ ? tabDataList.find(tab => tab.name.value === newName)
9589
9654
  : null;
9590
9655
 
9591
9656
  if (oldTab && newTab) {
@@ -9609,7 +9674,7 @@ var QTabs = createComponent({
9609
9674
  : `translate3d(${ oldPos.left - newPos.left }px,0,0) scale3d(${ newPos.width ? oldPos.width / newPos.width : 1 },1,1)`;
9610
9675
 
9611
9676
  // allow scope updates to kick in (QRouteTab needs more time)
9612
- nextTick(() => {
9677
+ registerAnimateTick(() => {
9613
9678
  animateTimer = setTimeout(() => {
9614
9679
  newEl.style.transition = 'transform .25s cubic-bezier(.4, 0, .2, 1)';
9615
9680
  newEl.style.transform = 'none';
@@ -9664,8 +9729,6 @@ var QTabs = createComponent({
9664
9729
 
9665
9730
  function animScrollTo (value) {
9666
9731
  stopAnimScroll();
9667
- scrollTowards(value);
9668
-
9669
9732
  scrollTimer = setInterval(() => {
9670
9733
  if (scrollTowards(value) === true) {
9671
9734
  stopAnimScroll();
@@ -9696,10 +9759,12 @@ var QTabs = createComponent({
9696
9759
 
9697
9760
  if (keyCode === 36) { // Home
9698
9761
  scrollToTabEl(tabs[ 0 ]);
9762
+ tabs[ 0 ].focus();
9699
9763
  return true
9700
9764
  }
9701
9765
  if (keyCode === 35) { // End
9702
9766
  scrollToTabEl(tabs[ len - 1 ]);
9767
+ tabs[ len - 1 ].focus();
9703
9768
  return true
9704
9769
  }
9705
9770
 
@@ -9765,77 +9830,113 @@ var QTabs = createComponent({
9765
9830
  return done
9766
9831
  }
9767
9832
 
9768
- function getRouteList () {
9769
- return tabList.filter(tab => tab.routerProps !== void 0 && tab.routerProps.hasRouterLink.value === true)
9833
+ function hasQueryIncluded (targetQuery, matchingQuery) {
9834
+ for (const key in targetQuery) {
9835
+ if (targetQuery[ key ] !== matchingQuery[ key ]) {
9836
+ return false
9837
+ }
9838
+ }
9839
+
9840
+ return true
9770
9841
  }
9771
9842
 
9772
9843
  // do not use directly; use verifyRouteModel() instead
9773
9844
  function updateActiveRoute () {
9774
- let name = null, wasActive = localFromRoute;
9845
+ let name = null, bestScore = { matchedLen: 0, queryDiff: 9999, hrefLen: 0 };
9775
9846
 
9776
- const
9777
- best = { matchedLen: 0, hrefLen: 0, exact: false, found: false },
9778
- { hash } = vm.proxy.$route,
9779
- model = currentModel.value;
9780
-
9781
- let wasItActive = wasActive === true
9782
- ? emptyFn
9783
- : tab => {
9784
- if (model === tab.name.value) {
9785
- wasActive = true;
9786
- wasItActive = emptyFn;
9787
- }
9788
- };
9847
+ const list = tabDataList.filter(tab => tab.routeData !== void 0 && tab.routeData.hasRouterLink.value === true);
9848
+ const { hash: currentHash, query: currentQuery } = proxy.$route;
9849
+ const currentQueryLen = Object.keys(currentQuery).length;
9789
9850
 
9790
- const tabList = getRouteList();
9851
+ // Vue Router does not keep account of hash & query when matching
9852
+ // so we're doing this as well
9791
9853
 
9792
- for (const tab of tabList) {
9793
- const exact = tab.routerProps.exact.value === true;
9854
+ for (const tab of list) {
9855
+ const exact = tab.routeData.exact.value === true;
9794
9856
 
9795
- if (
9796
- tab.routerProps[ exact === true ? 'linkIsExactActive' : 'linkIsActive' ].value !== true
9797
- || (best.exact === true && exact !== true)
9798
- ) {
9799
- wasItActive(tab);
9857
+ if (tab.routeData[ exact === true ? 'linkIsExactActive' : 'linkIsActive' ].value !== true) {
9858
+ // it cannot match anything as it's not active nor exact-active
9800
9859
  continue
9801
9860
  }
9802
9861
 
9803
- const
9804
- linkRoute = tab.routerProps.linkRoute.value,
9805
- tabHash = linkRoute.hash;
9862
+ const { hash, query, matched, href } = tab.routeData.resolvedLink.value;
9863
+ const queryLen = Object.keys(query).length;
9806
9864
 
9807
- // Vue Router does not match the hash too, even if link is set to "exact"
9808
9865
  if (exact === true) {
9809
- if (hash === tabHash) {
9810
- name = tab.name.value;
9811
- break
9866
+ if (hash !== currentHash) {
9867
+ // it's set to exact but it doesn't matches the hash
9868
+ continue
9812
9869
  }
9813
- else if (hash !== '' && tabHash !== '') {
9814
- wasItActive(tab);
9870
+
9871
+ if (
9872
+ queryLen !== currentQueryLen
9873
+ || hasQueryIncluded(currentQuery, query) === false
9874
+ ) {
9875
+ // it's set to exact but it doesn't matches the query
9815
9876
  continue
9816
9877
  }
9878
+
9879
+ // yey, we found the perfect match (route + hash + query)
9880
+ name = tab.name.value;
9881
+ break
9817
9882
  }
9818
9883
 
9819
- const
9820
- matchedLen = linkRoute.matched.length,
9821
- hrefLen = linkRoute.href.length - tabHash.length;
9884
+ if (hash !== '' && hash !== currentHash) {
9885
+ // it has hash and it doesn't matches
9886
+ continue
9887
+ }
9822
9888
 
9823
9889
  if (
9824
- matchedLen === best.matchedLen
9825
- ? hrefLen > best.hrefLen
9826
- : matchedLen > best.matchedLen
9890
+ queryLen !== 0
9891
+ && hasQueryIncluded(query, currentQuery) === false
9827
9892
  ) {
9893
+ // it has query and it doesn't includes the current one
9894
+ continue
9895
+ }
9896
+
9897
+ const newScore = {
9898
+ matchedLen: matched.length,
9899
+ queryDiff: currentQueryLen - queryLen,
9900
+ hrefLen: href.length - hash.length
9901
+ };
9902
+
9903
+ if (newScore.matchedLen > bestScore.matchedLen) {
9904
+ // it matches more routes so it's more specific so we set it as current champion
9905
+ name = tab.name.value;
9906
+ bestScore = newScore;
9907
+ continue
9908
+ }
9909
+ else if (newScore.matchedLen !== bestScore.matchedLen) {
9910
+ // it matches less routes than the current champion so we discard it
9911
+ continue
9912
+ }
9913
+
9914
+ if (newScore.queryDiff < bestScore.queryDiff) {
9915
+ // query is closer to the current one so we set it as current champion
9828
9916
  name = tab.name.value;
9829
- Object.assign(best, { matchedLen, hrefLen, exact });
9917
+ bestScore = newScore;
9918
+ }
9919
+ else if (newScore.queryDiff !== bestScore.queryDiff) {
9920
+ // it matches less routes than the current champion so we discard it
9830
9921
  continue
9831
9922
  }
9832
9923
 
9833
- wasItActive(tab);
9924
+ if (newScore.hrefLen > bestScore.hrefLen) {
9925
+ // href is lengthier so it's more specific so we set it as current champion
9926
+ name = tab.name.value;
9927
+ bestScore = newScore;
9928
+ }
9834
9929
  }
9835
9930
 
9836
- if (wasActive === true || name !== null) {
9837
- updateModel({ name, setCurrent: true, fromRoute: true });
9931
+ if (
9932
+ name === null
9933
+ && tabDataList.some(tab => tab.routeData === void 0 && tab.name.value === currentModel.value) === true
9934
+ ) {
9935
+ // we shouldn't interfere if non-route tab is active
9936
+ return
9838
9937
  }
9938
+
9939
+ updateModel({ name, setCurrent: true });
9839
9940
  }
9840
9941
 
9841
9942
  function onFocusin (e) {
@@ -9853,6 +9954,7 @@ var QTabs = createComponent({
9853
9954
  // (it might be other elements focused, like additional QBtn)
9854
9955
  if (tab && rootRef.value.contains(tab) === true) {
9855
9956
  hasFocus.value = true;
9957
+ scrollable.value === true && scrollToTabEl(tab);
9856
9958
  }
9857
9959
  }
9858
9960
  }
@@ -9862,22 +9964,52 @@ var QTabs = createComponent({
9862
9964
  }
9863
9965
 
9864
9966
  function verifyRouteModel () {
9865
- if ($tabs.avoidRouteWatcher !== true) {
9866
- registerTimeout(updateActiveRoute);
9967
+ if ($tabs.avoidRouteWatcher === false) {
9968
+ registerScrollToTabTimeout(updateActiveRoute);
9969
+ }
9970
+ else {
9971
+ removeScrollToTabTimeout();
9867
9972
  }
9868
9973
  }
9869
9974
 
9870
- function registerTab (getTab) {
9871
- tabList.push(getTab);
9975
+ function watchRoute () {
9976
+ if (unwatchRoute === void 0) {
9977
+ const unwatch = watch(() => proxy.$route.fullPath, verifyRouteModel);
9978
+ unwatchRoute = () => {
9979
+ unwatch();
9980
+ unwatchRoute = void 0;
9981
+ };
9982
+ }
9983
+ }
9872
9984
 
9873
- const routeList = getRouteList();
9985
+ function registerTab (tabData) {
9986
+ tabDataList.push(tabData);
9987
+ tabDataListLen.value++;
9874
9988
 
9875
- if (routeList.length > 0) {
9876
- if (unwatchRoute === void 0) {
9877
- unwatchRoute = watch(() => vm.proxy.$route, verifyRouteModel);
9878
- }
9989
+ recalculateScroll();
9879
9990
 
9880
- verifyRouteModel();
9991
+ // if it's a QTab
9992
+ if (tabData.routeData === void 0) {
9993
+ // we should position to the currently active tab (if any)
9994
+ registerScrollToTabTimeout(() => {
9995
+ if (scrollable.value === true) {
9996
+ const value = currentModel.value;
9997
+ const newTab = value !== void 0 && value !== null && value !== ''
9998
+ ? tabDataList.find(tab => tab.name.value === value)
9999
+ : null;
10000
+
10001
+ newTab && scrollToTabEl(newTab.rootRef.value);
10002
+ }
10003
+ });
10004
+ }
10005
+ // else if it's a QRouteTab with a valid link
10006
+ else {
10007
+ // start watching route
10008
+ watchRoute();
10009
+
10010
+ if (tabData.routeData.hasRouterLink.value === true) {
10011
+ verifyRouteModel();
10012
+ }
9881
10013
  }
9882
10014
  }
9883
10015
 
@@ -9889,16 +10021,18 @@ var QTabs = createComponent({
9889
10021
  * always check the existing list again and infer the changes.
9890
10022
  */
9891
10023
  function unregisterTab (tabData) {
9892
- tabList.splice(tabList.indexOf(tabData), 1);
10024
+ tabDataList.splice(tabDataList.indexOf(tabData), 1);
10025
+ tabDataListLen.value--;
9893
10026
 
9894
- if (unwatchRoute !== void 0) {
9895
- const routeList = getRouteList();
10027
+ recalculateScroll();
9896
10028
 
9897
- if (routeList.length === 0) {
10029
+ if (unwatchRoute !== void 0 && tabData.routeData !== void 0) {
10030
+ // unwatch route if we don't have any QRouteTabs left
10031
+ if (tabDataList.every(tab => tab.routeData === void 0) === true) {
9898
10032
  unwatchRoute();
9899
- unwatchRoute = void 0;
9900
10033
  }
9901
10034
 
10035
+ // then update model
9902
10036
  verifyRouteModel();
9903
10037
  }
9904
10038
  }
@@ -9907,33 +10041,38 @@ var QTabs = createComponent({
9907
10041
  currentModel,
9908
10042
  tabProps,
9909
10043
  hasFocus,
10044
+ hasActiveTab,
9910
10045
 
9911
10046
  registerTab,
9912
10047
  unregisterTab,
9913
10048
 
9914
10049
  verifyRouteModel,
9915
10050
  updateModel,
9916
- recalculateScroll,
9917
10051
  onKbdNavigate,
9918
10052
 
9919
- avoidRouteWatcher: false
10053
+ avoidRouteWatcher: false // false | string (uid)
9920
10054
  };
9921
10055
 
9922
10056
  provide(tabsKey, $tabs);
9923
10057
 
9924
- onBeforeUnmount(() => {
10058
+ function cleanup () {
9925
10059
  clearTimeout(animateTimer);
10060
+ stopAnimScroll();
9926
10061
  unwatchRoute !== void 0 && unwatchRoute();
9927
- });
10062
+ }
9928
10063
 
9929
- let shouldActivate = false;
10064
+ let hadRouteWatcher;
10065
+
10066
+ onBeforeUnmount(cleanup);
9930
10067
 
9931
10068
  onDeactivated(() => {
9932
- shouldActivate = true;
10069
+ hadRouteWatcher = unwatchRoute !== void 0;
10070
+ cleanup();
9933
10071
  });
9934
10072
 
9935
10073
  onActivated(() => {
9936
- shouldActivate === true && recalculateScroll();
10074
+ hadRouteWatcher === true && watchRoute();
10075
+ recalculateScroll();
9937
10076
  });
9938
10077
 
9939
10078
  return () => {
@@ -9952,22 +10091,22 @@ var QTabs = createComponent({
9952
10091
  class: 'q-tabs__arrow q-tabs__arrow--left absolute q-tab__icon'
9953
10092
  + (leftArrow.value === true ? '' : ' q-tabs__arrow--faded'),
9954
10093
  name: props.leftIcon || $q.iconSet.tabs[ props.vertical === true ? 'up' : 'left' ],
9955
- onMousedown: scrollToStart,
10094
+ onMousedownPassive: scrollToStart,
9956
10095
  onTouchstartPassive: scrollToStart,
9957
- onMouseup: stopAnimScroll,
9958
- onMouseleave: stopAnimScroll,
9959
- onTouchend: stopAnimScroll
10096
+ onMouseupPassive: stopAnimScroll,
10097
+ onMouseleavePassive: stopAnimScroll,
10098
+ onTouchendPassive: stopAnimScroll
9960
10099
  }),
9961
10100
 
9962
10101
  h(QIcon, {
9963
10102
  class: 'q-tabs__arrow q-tabs__arrow--right absolute q-tab__icon'
9964
10103
  + (rightArrow.value === true ? '' : ' q-tabs__arrow--faded'),
9965
10104
  name: props.rightIcon || $q.iconSet.tabs[ props.vertical === true ? 'down' : 'right' ],
9966
- onMousedown: scrollToEnd,
10105
+ onMousedownPassive: scrollToEnd,
9967
10106
  onTouchstartPassive: scrollToEnd,
9968
- onMouseup: stopAnimScroll,
9969
- onMouseleave: stopAnimScroll,
9970
- onTouchend: stopAnimScroll
10107
+ onMouseupPassive: stopAnimScroll,
10108
+ onMouseleavePassive: stopAnimScroll,
10109
+ onTouchendPassive: stopAnimScroll
9971
10110
  })
9972
10111
  );
9973
10112
 
@@ -9982,7 +10121,7 @@ var QTabs = createComponent({
9982
10121
  }
9983
10122
  });
9984
10123
 
9985
- let uid$2 = 0;
10124
+ let id$1 = 0;
9986
10125
 
9987
10126
  const useTabEmits = [ 'click', 'keydown' ];
9988
10127
 
@@ -9995,7 +10134,7 @@ const useTabProps = {
9995
10134
 
9996
10135
  name: {
9997
10136
  type: [ Number, String ],
9998
- default: () => `t_${ uid$2++ }`
10137
+ default: () => `t_${ id$1++ }`
9999
10138
  },
10000
10139
 
10001
10140
  noCaps: Boolean,
@@ -10011,7 +10150,7 @@ const useTabProps = {
10011
10150
  }
10012
10151
  };
10013
10152
 
10014
- function useTab (props, slots, emit, routerProps) {
10153
+ function useTab (props, slots, emit, routeData) {
10015
10154
  const $tabs = inject(tabsKey, () => {
10016
10155
  console.error('QTab/QRouteTab component needs to be child of QTabs');
10017
10156
  });
@@ -10048,7 +10187,7 @@ function useTab (props, slots, emit, routerProps) {
10048
10187
  + (props.icon && props.label && $tabs.tabProps.value.inlineLabel === false ? ' q-tab--full' : '')
10049
10188
  + (props.noCaps === true || $tabs.tabProps.value.noCaps === true ? ' q-tab--no-caps' : '')
10050
10189
  + (props.disable === true ? ' disabled' : ' q-focusable q-hoverable cursor-pointer')
10051
- + (routerProps !== void 0 && routerProps.linkClass.value !== '' ? ` ${ routerProps.linkClass.value }` : '')
10190
+ + (routeData !== void 0 ? routeData.linkClass.value : '')
10052
10191
  );
10053
10192
 
10054
10193
  const innerClass = computed(() =>
@@ -10058,53 +10197,77 @@ function useTab (props, slots, emit, routerProps) {
10058
10197
  );
10059
10198
 
10060
10199
  const tabIndex = computed(() => (
10061
- props.disable === true || $tabs.hasFocus.value === true
10200
+ (
10201
+ props.disable === true
10202
+ || $tabs.hasFocus.value === true
10203
+ || (isActive.value === false && $tabs.hasActiveTab.value === true)
10204
+ )
10062
10205
  ? -1
10063
10206
  : props.tabindex || 0
10064
10207
  ));
10065
10208
 
10066
10209
  function onClick (e, keyboard) {
10067
- keyboard !== true && blurTargetRef.value !== null && blurTargetRef.value.focus();
10210
+ if (keyboard !== true && blurTargetRef.value !== null) {
10211
+ blurTargetRef.value.focus();
10212
+ }
10068
10213
 
10069
- if (props.disable !== true) {
10070
- let go;
10214
+ if (props.disable === true) {
10215
+ // we should hinder native navigation though
10216
+ if (routeData !== void 0 && routeData.hasRouterLink.value === true) {
10217
+ stopAndPrevent(e);
10218
+ }
10219
+ return
10220
+ }
10071
10221
 
10072
- if (routerProps !== void 0) {
10073
- if (routerProps.hasRouterLink.value === true) {
10074
- go = () => {
10075
- e.__qNavigate = true;
10076
- $tabs.avoidRouteWatcher = true;
10222
+ // do we have a QTab?
10223
+ if (routeData === void 0) {
10224
+ $tabs.updateModel({ name: props.name });
10225
+ emit('click', e);
10226
+ return
10227
+ }
10077
10228
 
10078
- const res = routerProps.navigateToRouterLink(e);
10229
+ if (routeData.hasRouterLink.value === true) {
10230
+ const go = (opts = {}) => {
10231
+ // if requiring to go to another route, then we
10232
+ // let the QTabs route watcher do its job,
10233
+ // otherwise directly select this
10234
+ let hardError;
10235
+ const reqId = opts.to === void 0 || isDeepEqual(opts.to, props.to) === true
10236
+ ? ($tabs.avoidRouteWatcher = uid$3())
10237
+ : null;
10079
10238
 
10080
- if (res === false) {
10239
+ return routeData.navigateToRouterLink(e, { ...opts, returnRouterError: true })
10240
+ .catch(err => { hardError = err; })
10241
+ .then(softError => {
10242
+ if (reqId === $tabs.avoidRouteWatcher) {
10081
10243
  $tabs.avoidRouteWatcher = false;
10244
+
10245
+ // if we don't have any hard errors or any soft errors, except for
10246
+ // when navigating to the same route (on all other soft errors,
10247
+ // like when navigation was aborted in a nav guard, we don't activate this tab)
10248
+ if (
10249
+ hardError === void 0 && (
10250
+ softError === void 0
10251
+ || softError.message.startsWith('Avoided redundant navigation') === true
10252
+ )
10253
+ ) {
10254
+ $tabs.updateModel({ name: props.name });
10255
+ }
10082
10256
  }
10083
- else {
10084
- res.then(err => {
10085
- $tabs.avoidRouteWatcher = false;
10086
10257
 
10087
- if (err === void 0) {
10088
- $tabs.updateModel({ name: props.name, fromRoute: true });
10089
- }
10090
- });
10258
+ if (opts.returnRouterError === true) {
10259
+ return hardError !== void 0 ? Promise.reject(hardError) : softError
10091
10260
  }
10092
- };
10093
- }
10094
- else {
10095
- emit('click', e);
10096
- return
10097
- }
10098
- }
10099
- else {
10100
- go = () => {
10101
- $tabs.updateModel({ name: props.name, fromRoute: false });
10102
- };
10103
- }
10261
+ })
10262
+ };
10104
10263
 
10105
10264
  emit('click', e, go);
10106
10265
  e.defaultPrevented !== true && go();
10266
+
10267
+ return
10107
10268
  }
10269
+
10270
+ emit('click', e);
10108
10271
  }
10109
10272
 
10110
10273
  function onKeydown (e) {
@@ -10178,17 +10341,15 @@ function useTab (props, slots, emit, routerProps) {
10178
10341
  name: computed(() => props.name),
10179
10342
  rootRef,
10180
10343
  tabIndicatorRef,
10181
- routerProps
10344
+ routeData
10182
10345
  };
10183
10346
 
10184
10347
  onBeforeUnmount(() => {
10185
10348
  $tabs.unregisterTab(tabData);
10186
- $tabs.recalculateScroll();
10187
10349
  });
10188
10350
 
10189
10351
  onMounted(() => {
10190
10352
  $tabs.registerTab(tabData);
10191
- $tabs.recalculateScroll();
10192
10353
  });
10193
10354
 
10194
10355
  function renderTab (tag, customData) {
@@ -14566,7 +14727,7 @@ var QDialog = createComponent({
14566
14727
  );
14567
14728
 
14568
14729
  const { preventBodyScroll } = usePreventScroll();
14569
- const { registerTimeout, removeTimeout } = useTimeout();
14730
+ const { registerTimeout } = useTimeout();
14570
14731
  const { registerTick, removeTick } = useTick();
14571
14732
 
14572
14733
  const { showPortal, hidePortal, portalIsAccessible, renderPortal } = usePortal(
@@ -14651,8 +14812,6 @@ var QDialog = createComponent({
14651
14812
  });
14652
14813
 
14653
14814
  function handleShow (evt) {
14654
- removeTimeout();
14655
- removeTick();
14656
14815
  addToHistory();
14657
14816
 
14658
14817
  refocusTarget = props.noRefocus === false && document.activeElement !== null
@@ -14667,7 +14826,11 @@ var QDialog = createComponent({
14667
14826
  document.activeElement !== null && document.activeElement.blur();
14668
14827
  registerTick(focus);
14669
14828
  }
14829
+ else {
14830
+ removeTick();
14831
+ }
14670
14832
 
14833
+ // should removeTimeout() if this gets removed
14671
14834
  registerTimeout(() => {
14672
14835
  if (vm.proxy.$q.platform.is.ios === true) {
14673
14836
  if (props.seamless !== true && document.activeElement) {
@@ -14703,7 +14866,6 @@ var QDialog = createComponent({
14703
14866
  }
14704
14867
 
14705
14868
  function handleHide (evt) {
14706
- removeTimeout();
14707
14869
  removeTick();
14708
14870
  removeFromHistory();
14709
14871
  cleanup(true);
@@ -14715,6 +14877,7 @@ var QDialog = createComponent({
14715
14877
  refocusTarget = null;
14716
14878
  }
14717
14879
 
14880
+ // should removeTimeout() if this gets removed
14718
14881
  registerTimeout(() => {
14719
14882
  hidePortal(true); // done hiding, now destroy
14720
14883
  animating.value = false;
@@ -14948,7 +15111,7 @@ var QDrawer = createComponent({
14948
15111
 
14949
15112
  const isDark = useDark(props, $q);
14950
15113
  const { preventBodyScroll } = usePreventScroll();
14951
- const { registerTimeout } = useTimeout();
15114
+ const { registerTimeout, removeTimeout } = useTimeout();
14952
15115
 
14953
15116
  const $layout = inject(layoutKey, () => {
14954
15117
  console.error('QDrawer needs to be child of QLayout');
@@ -15018,9 +15181,12 @@ var QDrawer = createComponent({
15018
15181
 
15019
15182
  cleanup();
15020
15183
 
15021
- noEvent !== true && registerTimeout(() => {
15022
- emit('hide', evt);
15023
- }, duration);
15184
+ if (noEvent !== true) {
15185
+ registerTimeout(() => { emit('hide', evt); }, duration);
15186
+ }
15187
+ else {
15188
+ removeTimeout();
15189
+ }
15024
15190
  }
15025
15191
 
15026
15192
  const { show, hide } = useModelToggle({
@@ -16009,7 +16175,7 @@ var QTooltip = createComponent({
16009
16175
  const hideOnRouteChange = computed(() => props.persistent !== true);
16010
16176
 
16011
16177
  const { registerTick, removeTick } = useTick();
16012
- const { registerTimeout, removeTimeout } = useTimeout();
16178
+ const { registerTimeout } = useTimeout();
16013
16179
  const { transition, transitionStyle } = useTransition(props, showing);
16014
16180
  const { localScrollTarget, changeScrollEvent, unconfigureScrollTarget } = useScrollTarget(props, configureScrollTarget);
16015
16181
 
@@ -16063,11 +16229,9 @@ var QTooltip = createComponent({
16063
16229
  }
16064
16230
 
16065
16231
  function handleShow (evt) {
16066
- removeTick();
16067
- removeTimeout();
16068
-
16069
16232
  showPortal();
16070
16233
 
16234
+ // should removeTick() if this gets removed
16071
16235
  registerTick(() => {
16072
16236
  observer = new MutationObserver(() => updatePosition());
16073
16237
  observer.observe(innerRef.value, { attributes: false, childList: true, characterData: true, subtree: true });
@@ -16082,6 +16246,7 @@ var QTooltip = createComponent({
16082
16246
  );
16083
16247
  }
16084
16248
 
16249
+ // should removeTimeout() if this gets removed
16085
16250
  registerTimeout(() => {
16086
16251
  showPortal(true); // done showing portal
16087
16252
  emit('show', evt);
@@ -16090,11 +16255,11 @@ var QTooltip = createComponent({
16090
16255
 
16091
16256
  function handleHide (evt) {
16092
16257
  removeTick();
16093
- removeTimeout();
16094
16258
  hidePortal();
16095
16259
 
16096
16260
  anchorCleanup();
16097
16261
 
16262
+ // should removeTimeout() if this gets removed
16098
16263
  registerTimeout(() => {
16099
16264
  hidePortal(true); // done hiding, now destroy
16100
16265
  emit('hide', evt);
@@ -16146,14 +16311,10 @@ var QTooltip = createComponent({
16146
16311
  addEvt(anchorEvents, 'tooltipTemp', evts);
16147
16312
  }
16148
16313
 
16149
- registerTimeout(() => {
16150
- show(evt);
16151
- }, props.delay);
16314
+ registerTimeout(() => { show(evt); }, props.delay);
16152
16315
  }
16153
16316
 
16154
16317
  function delayHide (evt) {
16155
- removeTimeout();
16156
-
16157
16318
  if ($q.platform.is.mobile === true) {
16158
16319
  cleanEvt(anchorEvents, 'tooltipTemp');
16159
16320
  clearSelection();
@@ -16163,9 +16324,8 @@ var QTooltip = createComponent({
16163
16324
  }, 10);
16164
16325
  }
16165
16326
 
16166
- registerTimeout(() => {
16167
- hide(evt);
16168
- }, props.hideDelay);
16327
+ // should removeTimeout() if this gets removed
16328
+ registerTimeout(() => { hide(evt); }, props.hideDelay);
16169
16329
  }
16170
16330
 
16171
16331
  function configureAnchorEl () {
@@ -16261,7 +16421,7 @@ var QItem = createComponent({
16261
16421
  const { proxy: { $q } } = getCurrentInstance();
16262
16422
 
16263
16423
  const isDark = useDark(props, $q);
16264
- const { hasRouterLink, hasLink, linkProps, linkClass, linkTag, navigateToRouterLink } = useRouterLink();
16424
+ const { hasLink, linkAttrs, linkClass, linkTag, navigateOnClick } = useRouterLink();
16265
16425
 
16266
16426
  const rootRef = ref(null);
16267
16427
  const blurTargetRef = ref(null);
@@ -16285,7 +16445,7 @@ var QItem = createComponent({
16285
16445
  ? linkClass.value
16286
16446
  : (
16287
16447
  props.active === true
16288
- ? `${ props.activeClass !== void 0 ? ` ${ props.activeClass }` : '' } q-item--active`
16448
+ ? ` q-item--active${ props.activeClass !== void 0 ? ` ${ props.activeClass }` : '' }`
16289
16449
  : ''
16290
16450
  )
16291
16451
  )
@@ -16321,8 +16481,7 @@ var QItem = createComponent({
16321
16481
  }
16322
16482
  }
16323
16483
 
16324
- hasRouterLink.value === true && navigateToRouterLink(e);
16325
- emit('click', e);
16484
+ navigateOnClick(e);
16326
16485
  }
16327
16486
  }
16328
16487
 
@@ -16363,7 +16522,7 @@ var QItem = createComponent({
16363
16522
 
16364
16523
  if (isClickable.value === true) {
16365
16524
  data.tabindex = props.tabindex || '0';
16366
- Object.assign(data, linkProps.value);
16525
+ Object.assign(data, linkAttrs.value);
16367
16526
  }
16368
16527
  else if (isActionable.value === true) {
16369
16528
  data[ 'aria-disabled' ] = 'true';
@@ -16716,24 +16875,21 @@ function useSplitAttrs (attrs, vnode) {
16716
16875
  const
16717
16876
  toString = Object.prototype.toString,
16718
16877
  hasOwn = Object.prototype.hasOwnProperty,
16719
- class2type = {};
16720
-
16721
- 'Boolean Number String Function Array Date RegExp Object'.split(' ').forEach(name => {
16722
- class2type[ '[object ' + name + ']' ] = name.toLowerCase();
16723
- });
16724
-
16725
- function type (obj) {
16726
- return obj === null ? String(obj) : class2type[ toString.call(obj) ] || 'object'
16727
- }
16878
+ notPlainObject = new Set(
16879
+ [ 'Boolean', 'Number', 'String', 'Function', 'Array', 'Date', 'RegExp' ]
16880
+ .map(name => '[object ' + name + ']')
16881
+ );
16728
16882
 
16729
16883
  function isPlainObject (obj) {
16730
- if (!obj || type(obj) !== 'object') {
16884
+ if (obj !== Object(obj) || notPlainObject.has(toString.call(obj)) === true) {
16731
16885
  return false
16732
16886
  }
16733
16887
 
16734
- if (obj.constructor
16735
- && !hasOwn.call(obj, 'constructor')
16736
- && !hasOwn.call(obj.constructor.prototype, 'isPrototypeOf')) {
16888
+ if (
16889
+ obj.constructor
16890
+ && hasOwn.call(obj, 'constructor') === false
16891
+ && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf') === false
16892
+ ) {
16737
16893
  return false
16738
16894
  }
16739
16895
 
@@ -16757,7 +16913,7 @@ function extend () {
16757
16913
  i = 2;
16758
16914
  }
16759
16915
 
16760
- if (Object(target) !== target && type(target) !== 'function') {
16916
+ if (Object(target) !== target && typeof target !== 'function') {
16761
16917
  target = {};
16762
16918
  }
16763
16919
 
@@ -16776,13 +16932,16 @@ function extend () {
16776
16932
  continue
16777
16933
  }
16778
16934
 
16779
- if (deep && copy && (isPlainObject(copy) || (copyIsArray = type(copy) === 'array'))) {
16780
- if (copyIsArray) {
16781
- copyIsArray = false;
16782
- clone = src && type(src) === 'array' ? src : [];
16935
+ if (
16936
+ deep === true
16937
+ && copy
16938
+ && ((copyIsArray = Array.isArray(copy)) || isPlainObject(copy) === true)
16939
+ ) {
16940
+ if (copyIsArray === true) {
16941
+ clone = Array.isArray(src) === true ? src : [];
16783
16942
  }
16784
16943
  else {
16785
- clone = src && isPlainObject(src) ? src : {};
16944
+ clone = isPlainObject(src) === true ? src : {};
16786
16945
  }
16787
16946
 
16788
16947
  target[ name ] = extend(deep, clone, copy);
@@ -17604,7 +17763,7 @@ var QExpansionItem = createComponent({
17604
17763
  );
17605
17764
 
17606
17765
  const blurTargetRef = ref(null);
17607
- const targetUid = uid$4();
17766
+ const targetUid = uid$3();
17608
17767
 
17609
17768
  const { show, hide, toggle } = useModelToggle({ showing });
17610
17769
 
@@ -17708,7 +17867,7 @@ var QExpansionItem = createComponent({
17708
17867
 
17709
17868
  function enterGroup () {
17710
17869
  if (uniqueId === void 0) {
17711
- uniqueId = uid$4();
17870
+ uniqueId = uid$3();
17712
17871
  }
17713
17872
 
17714
17873
  if (showing.value === true) {
@@ -18025,7 +18184,7 @@ var QFab = createComponent({
18025
18184
  setup (props, { slots }) {
18026
18185
  const triggerRef = ref(null);
18027
18186
  const showing = ref(props.modelValue === true);
18028
- const targetUid = uid$4();
18187
+ const targetUid = uid$3();
18029
18188
 
18030
18189
  const { proxy: { $q } } = getCurrentInstance();
18031
18190
  const { formClass, labelProps } = useFab(props, showing);
@@ -18474,7 +18633,7 @@ function useValidate (focused, innerLoading) {
18474
18633
  }
18475
18634
 
18476
18635
  function getTargetUid (val) {
18477
- return val === void 0 ? `f_${ uid$4() }` : val
18636
+ return val === void 0 ? `f_${ uid$3() }` : val
18478
18637
  }
18479
18638
 
18480
18639
  function fieldValueIsFilled (val) {
@@ -22756,8 +22915,7 @@ var QNoSsr = createComponent({
22756
22915
  const svg$m = h('svg', {
22757
22916
  key: 'svg',
22758
22917
  class: 'q-radio__bg absolute non-selectable',
22759
- viewBox: '0 0 24 24',
22760
- 'aria-hidden': 'true'
22918
+ viewBox: '0 0 24 24'
22761
22919
  }, [
22762
22920
  h('path', {
22763
22921
  d: 'M12,22a10,10 0 0 1 -10,-10a10,10 0 0 1 10,-10a10,10 0 0 1 10,10a10,10 0 0 1 -10,10m0,-22a12,12 0 0 0 -12,12a12,12 0 0 0 12,12a12,12 0 0 0 12,-12a12,12 0 0 0 -12,-12'
@@ -22902,7 +23060,8 @@ var QRadio = createComponent({
22902
23060
  const child = [
22903
23061
  h('div', {
22904
23062
  class: innerClass.value,
22905
- style: sizeStyle.value
23063
+ style: sizeStyle.value,
23064
+ 'aria-hidden': 'true'
22906
23065
  }, content)
22907
23066
  ];
22908
23067
 
@@ -24079,16 +24238,13 @@ var QPopupEdit = createComponent({
24079
24238
  let validated = false;
24080
24239
 
24081
24240
  const scope = computed(() => {
24082
- const acc = {
24241
+ return injectProp({
24083
24242
  initialValue: initialValue.value,
24084
24243
  validate: props.validate,
24085
24244
  set,
24086
24245
  cancel,
24087
24246
  updatePosition
24088
- };
24089
-
24090
- injectProp(acc, 'value', () => currentModel.value, val => { currentModel.value = val; });
24091
- return acc
24247
+ }, 'value', () => currentModel.value, val => { currentModel.value = val; })
24092
24248
  });
24093
24249
 
24094
24250
  function set () {
@@ -25025,6 +25181,8 @@ var QRating = createComponent({
25025
25181
  iconHalf: [ String, Array ],
25026
25182
  iconSelected: [ String, Array ],
25027
25183
 
25184
+ iconAriaLabel: [ String, Array ],
25185
+
25028
25186
  color: [ String, Array ],
25029
25187
  colorHalf: [ String, Array ],
25030
25188
  colorSelected: [ String, Array ],
@@ -25090,11 +25248,29 @@ var QRating = createComponent({
25090
25248
  }
25091
25249
  });
25092
25250
 
25251
+ const iconLabel = computed(() => {
25252
+ if (typeof props.iconAriaLabel === 'string') {
25253
+ const label = props.iconAriaLabel.length > 0 ? `${ props.iconAriaLabel } ` : '';
25254
+ return i => `${ label }${ i }`
25255
+ }
25256
+
25257
+ if (Array.isArray(props.iconAriaLabel) === true) {
25258
+ const iMax = props.iconAriaLabel.length;
25259
+
25260
+ if (iMax > 0) {
25261
+ return i => props.iconAriaLabel[ Math.min(i, iMax) - 1 ]
25262
+ }
25263
+ }
25264
+
25265
+ return (i, label) => `${ label } ${ i }`
25266
+ });
25267
+
25093
25268
  const stars = computed(() => {
25094
25269
  const
25095
25270
  acc = [],
25096
25271
  icons = iconData.value,
25097
- ceil = Math.ceil(props.modelValue);
25272
+ ceil = Math.ceil(props.modelValue),
25273
+ tabindex = editable.value === true ? 0 : null;
25098
25274
 
25099
25275
  const halfIndex = props.iconHalf === void 0 || ceil === props.modelValue
25100
25276
  ? -1
@@ -25111,7 +25287,16 @@ var QRating = createComponent({
25111
25287
  icons.selColor !== void 0 && active === true
25112
25288
  ? (i <= icons.selColorLen ? props.colorSelected[ i - 1 ] : icons.selColor)
25113
25289
  : (i <= icons.colorLen ? props.color[ i - 1 ] : icons.color)
25114
- );
25290
+ ),
25291
+ name = (
25292
+ half === true
25293
+ ? (i <= icons.halfIconLen ? props.iconHalf[ i - 1 ] : icons.halfIcon)
25294
+ : (
25295
+ icons.selIcon !== void 0 && (active === true || exSelected === true)
25296
+ ? (i <= icons.selIconLen ? props.iconSelected[ i - 1 ] : icons.selIcon)
25297
+ : (i <= icons.iconLen ? props.icon[ i - 1 ] : icons.icon)
25298
+ )
25299
+ ) || $q.iconSet.rating.icon;
25115
25300
 
25116
25301
  acc.push({
25117
25302
  name: (
@@ -25124,7 +25309,14 @@ var QRating = createComponent({
25124
25309
  )
25125
25310
  ) || $q.iconSet.rating.icon,
25126
25311
 
25127
- classes: 'q-rating__icon'
25312
+ attrs: {
25313
+ tabindex,
25314
+ role: 'radio',
25315
+ 'aria-checked': props.modelValue === i ? 'true' : 'false',
25316
+ 'aria-label': iconLabel.value(i, name)
25317
+ },
25318
+
25319
+ iconClass: 'q-rating__icon'
25128
25320
  + (active === true || half === true ? ' q-rating__icon--active' : '')
25129
25321
  + (exSelected === true ? ' q-rating__icon--exselected' : '')
25130
25322
  + (mouseModel.value === i ? ' q-rating__icon--hovered' : '')
@@ -25136,15 +25328,17 @@ var QRating = createComponent({
25136
25328
  });
25137
25329
 
25138
25330
  const attributes = computed(() => {
25331
+ const attrs = { role: 'radiogroup' };
25332
+
25139
25333
  if (props.disable === true) {
25140
- return { 'aria-disabled': 'true' }
25334
+ attrs[ 'aria-disabled' ] = 'true';
25141
25335
  }
25142
25336
  if (props.readonly === true) {
25143
- return { 'aria-readonly': 'true' }
25337
+ attrs[ 'aria-readonly' ] = 'true';
25144
25338
  }
25145
- });
25146
25339
 
25147
- const tabindex = computed(() => (editable.value === true ? 0 : null));
25340
+ return attrs
25341
+ });
25148
25342
 
25149
25343
  function set (value) {
25150
25344
  if (editable.value === true) {
@@ -25195,7 +25389,7 @@ var QRating = createComponent({
25195
25389
  return () => {
25196
25390
  const child = [];
25197
25391
 
25198
- stars.value.forEach(({ classes, name }, index) => {
25392
+ stars.value.forEach(({ iconClass, name, attrs }, index) => {
25199
25393
  const i = index + 1;
25200
25394
 
25201
25395
  child.push(
@@ -25203,7 +25397,7 @@ var QRating = createComponent({
25203
25397
  key: i,
25204
25398
  ref: vm => { iconRefs[ `rt${ i }` ] = vm; },
25205
25399
  class: 'q-rating__icon-container flex flex-center',
25206
- tabindex: tabindex.value,
25400
+ ...attrs,
25207
25401
  onClick () { set(i); },
25208
25402
  onMouseover () { setHoverValue(i); },
25209
25403
  onMouseout: resetMouseModel,
@@ -25212,7 +25406,7 @@ var QRating = createComponent({
25212
25406
  onKeyup (e) { onKeyup(e, i); }
25213
25407
  }, hMergeSlot(
25214
25408
  slots[ `tip-${ i }` ],
25215
- [ h(QIcon, { class: classes, name }) ]
25409
+ [ h(QIcon, { class: iconClass, name }) ]
25216
25410
  ))
25217
25411
  );
25218
25412
  });
@@ -30662,10 +30856,12 @@ var QStep = createComponent({
30662
30856
  default: true
30663
30857
  },
30664
30858
  done: Boolean,
30665
- error: Boolean
30859
+ error: Boolean,
30860
+
30861
+ onScroll: [ Function, Array ]
30666
30862
  },
30667
30863
 
30668
- setup (props, { attrs, slots }) {
30864
+ setup (props, { slots, emit }) {
30669
30865
  const { proxy: { $q } } = getCurrentInstance();
30670
30866
 
30671
30867
  const $stepper = inject(stepperKey, () => {
@@ -30689,7 +30885,7 @@ var QStep = createComponent({
30689
30885
  if (target.scrollTop > 0) {
30690
30886
  target.scrollTop = 0;
30691
30887
  }
30692
- attrs.onScroll !== void 0 && attrs.onScroll(e);
30888
+ props.onScroll !== void 0 && emit('scroll', e);
30693
30889
  }
30694
30890
  }
30695
30891
  ));
@@ -32158,11 +32354,9 @@ var QTable = createComponent({
32158
32354
  function getBodyScope (data) {
32159
32355
  injectBodyCommonScope(data);
32160
32356
 
32161
- data.cols = data.cols.map(col => {
32162
- const c = { ...col };
32163
- injectProp(c, 'value', () => getCellValue(col, data.row));
32164
- return c
32165
- });
32357
+ data.cols = data.cols.map(
32358
+ col => injectProp({ ...col }, 'value', () => getCellValue(col, data.row))
32359
+ );
32166
32360
 
32167
32361
  return data
32168
32362
  }
@@ -32801,7 +32995,9 @@ var QRouteTab = createComponent({
32801
32995
  emits: useTabEmits,
32802
32996
 
32803
32997
  setup (props, { slots, emit }) {
32804
- const rData = useRouterLink();
32998
+ const routeData = useRouterLink({
32999
+ useDisableForRouterLinkProps: false
33000
+ });
32805
33001
 
32806
33002
  const { renderTab, $tabs } = useTab(
32807
33003
  props,
@@ -32809,15 +33005,15 @@ var QRouteTab = createComponent({
32809
33005
  emit,
32810
33006
  {
32811
33007
  exact: computed(() => props.exact),
32812
- ...rData
33008
+ ...routeData
32813
33009
  }
32814
33010
  );
32815
33011
 
32816
- watch(() => props.name + props.exact + (rData.linkRoute.value || {}).href, () => {
33012
+ watch(() => `${ props.name } | ${ props.exact } | ${ (routeData.resolvedLink.value || {}).href }`, () => {
32817
33013
  $tabs.verifyRouteModel();
32818
33014
  });
32819
33015
 
32820
- return () => renderTab(rData.linkTag.value, rData.linkProps.value)
33016
+ return () => renderTab(routeData.linkTag.value, routeData.linkAttrs.value)
32821
33017
  }
32822
33018
  });
32823
33019
 
@@ -34510,7 +34706,7 @@ var QTree = createComponent({
34510
34706
  emit('update:selected', meta.key !== props.selected ? meta.key : null);
34511
34707
  }
34512
34708
  else if (meta.key !== props.selected) {
34513
- emit('update:selected', meta.key || null);
34709
+ emit('update:selected', meta.key === void 0 ? null : meta.key);
34514
34710
  }
34515
34711
  }
34516
34712
  else {
@@ -37196,7 +37392,7 @@ var TouchRepeat = createDirective({
37196
37392
 
37197
37393
  client.has.touch === true && addEvt(ctx, 'main', [
37198
37394
  [ el, 'touchstart', 'touchStart', `passive${ modifiers.capture === true ? 'Capture' : '' }` ],
37199
- [ el, 'touchend', 'noop', 'notPassiveCapture' ]
37395
+ [ el, 'touchend', 'noop', 'passiveCapture' ]
37200
37396
  ]);
37201
37397
 
37202
37398
  keyboard.length > 0 && addEvt(ctx, 'main', [
@@ -39802,7 +39998,7 @@ function parsePromises (sequentialPromises) {
39802
39998
  * Default: { threadsNumber: 1, abortOnFail: true }
39803
39999
  * When configuring threadsNumber AND using http requests, be
39804
40000
  * aware of the maximum threads that the hosting browser
39805
- * supports (usually 3); any number of threads above that
40001
+ * supports (usually 5); any number of threads above that
39806
40002
  * won't add any real benefits
39807
40003
  * @returns Promise<Array<Object> | Object>
39808
40004
  * With opts.abortOnFail set to true (which is default):
@@ -39887,10 +40083,10 @@ function runSequentialPromises (
39887
40083
  */
39888
40084
 
39889
40085
  const Quasar = {
39890
- version: '2.8.4',
40086
+ version: '2.9.1',
39891
40087
  install: installQuasar,
39892
40088
  lang: Plugin$8,
39893
40089
  iconSet: Plugin$7
39894
40090
  };
39895
40091
 
39896
- export { AddressbarColor, Plugin$6 as AppFullscreen, Plugin$5 as AppVisibility, BottomSheet, ClosePopup, Plugin$4 as Cookies, Plugin$9 as Dark, Dialog, EventBus, Intersection, Plugin$2 as Loading, Plugin$3 as LoadingBar, Plugin$1 as LocalStorage, Meta, Morph, Mutation, Notify, Platform, QAjaxBar, QAvatar, QBadge, QBanner, QBar, QBreadcrumbs, QBreadcrumbsEl, QBtn, QBtnDropdown, QBtnGroup, QBtnToggle, QCard, QCardActions, QCardSection, QCarousel, QCarouselControl, QCarouselSlide, QChatMessage, QCheckbox, QChip, QCircularProgress, QColor, QDate, QDialog, QDrawer, QEditor, QExpansionItem, QFab, QFabAction, QField, QFile, QFooter, QForm, QFormChildMixin, QHeader, QIcon, QImg, QInfiniteScroll, QInnerLoading, QInput, QIntersection, QItem, QItemLabel, QItemSection, QKnob, QLayout, QLinearProgress, QList, QMarkupTable, QMenu, QNoSsr, QOptionGroup, QPage, QPageContainer, QPageScroller, QPageSticky, QPagination, QParallax, QPopupEdit, QPopupProxy, QPullToRefresh, QRadio, QRange, QRating, QResizeObserver, QResponsive, QRouteTab, QScrollArea, QScrollObserver, QSelect, QSeparator, QSkeleton, QSlideItem, QSlideTransition, QSlider, QSpace, QSpinner, QSpinnerAudio, QSpinnerBall, QSpinnerBars, QSpinnerBox, QSpinnerClock, QSpinnerComment, QSpinnerCube, QSpinnerDots, QSpinnerFacebook, QSpinnerGears, QSpinnerGrid, QSpinnerHearts, QSpinnerHourglass, QSpinnerInfinity, QSpinnerIos, QSpinnerOrbit, QSpinnerOval, QSpinnerPie, QSpinnerPuff, QSpinnerRadio, QSpinnerRings, QSpinnerTail, QSplitter, QStep, QStepper, QStepperNavigation, QTab, QTabPanel, QTabPanels, QTable, QTabs, QTd, QTh, QTime, QTimeline, QTimelineEntry, QToggle, QToolbar, QToolbarTitle, QTooltip, QTr, QTree, QUploader, QUploaderAddTrigger, QVideo, QVirtualScroll, Quasar, Ripple, Screen, Scroll, ScrollFire, Plugin as SessionStorage, TouchHold, TouchPan, TouchRepeat, TouchSwipe, cloneDeep as clone, colors, copyToClipboard, createMetaMixin, createUploaderComponent, date, debounce, dom, event, exportFile, extend, format, frameDebounce, getCssVar, is, morph, noop, openUrl as openURL, patterns, runSequentialPromises, scroll, setCssVar, throttle, uid$4 as uid, useDialogPluginComponent, useFormChild, useMeta, useQuasar };
40092
+ export { AddressbarColor, Plugin$6 as AppFullscreen, Plugin$5 as AppVisibility, BottomSheet, ClosePopup, Plugin$4 as Cookies, Plugin$9 as Dark, Dialog, EventBus, Intersection, Plugin$2 as Loading, Plugin$3 as LoadingBar, Plugin$1 as LocalStorage, Meta, Morph, Mutation, Notify, Platform, QAjaxBar, QAvatar, QBadge, QBanner, QBar, QBreadcrumbs, QBreadcrumbsEl, QBtn, QBtnDropdown, QBtnGroup, QBtnToggle, QCard, QCardActions, QCardSection, QCarousel, QCarouselControl, QCarouselSlide, QChatMessage, QCheckbox, QChip, QCircularProgress, QColor, QDate, QDialog, QDrawer, QEditor, QExpansionItem, QFab, QFabAction, QField, QFile, QFooter, QForm, QFormChildMixin, QHeader, QIcon, QImg, QInfiniteScroll, QInnerLoading, QInput, QIntersection, QItem, QItemLabel, QItemSection, QKnob, QLayout, QLinearProgress, QList, QMarkupTable, QMenu, QNoSsr, QOptionGroup, QPage, QPageContainer, QPageScroller, QPageSticky, QPagination, QParallax, QPopupEdit, QPopupProxy, QPullToRefresh, QRadio, QRange, QRating, QResizeObserver, QResponsive, QRouteTab, QScrollArea, QScrollObserver, QSelect, QSeparator, QSkeleton, QSlideItem, QSlideTransition, QSlider, QSpace, QSpinner, QSpinnerAudio, QSpinnerBall, QSpinnerBars, QSpinnerBox, QSpinnerClock, QSpinnerComment, QSpinnerCube, QSpinnerDots, QSpinnerFacebook, QSpinnerGears, QSpinnerGrid, QSpinnerHearts, QSpinnerHourglass, QSpinnerInfinity, QSpinnerIos, QSpinnerOrbit, QSpinnerOval, QSpinnerPie, QSpinnerPuff, QSpinnerRadio, QSpinnerRings, QSpinnerTail, QSplitter, QStep, QStepper, QStepperNavigation, QTab, QTabPanel, QTabPanels, QTable, QTabs, QTd, QTh, QTime, QTimeline, QTimelineEntry, QToggle, QToolbar, QToolbarTitle, QTooltip, QTr, QTree, QUploader, QUploaderAddTrigger, QVideo, QVirtualScroll, Quasar, Ripple, Screen, Scroll, ScrollFire, Plugin as SessionStorage, TouchHold, TouchPan, TouchRepeat, TouchSwipe, cloneDeep as clone, colors, copyToClipboard, createMetaMixin, createUploaderComponent, date, debounce, dom, event, exportFile, extend, format, frameDebounce, getCssVar, is, morph, noop, openUrl as openURL, patterns, runSequentialPromises, scroll, setCssVar, throttle, uid$3 as uid, useDialogPluginComponent, useFormChild, useMeta, useQuasar };