quasar 2.21.3 → 2.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (243) hide show
  1. package/README.md +1 -1
  2. package/dist/api/Lang.json +1 -1
  3. package/dist/api/QUploader.json +1 -1
  4. package/dist/icon-set/bootstrap-icons.umd.prod.js +1 -1
  5. package/dist/icon-set/eva-icons.umd.prod.js +1 -1
  6. package/dist/icon-set/fontawesome-v5-pro.umd.prod.js +1 -1
  7. package/dist/icon-set/fontawesome-v5.umd.prod.js +1 -1
  8. package/dist/icon-set/fontawesome-v6-pro.umd.prod.js +1 -1
  9. package/dist/icon-set/fontawesome-v6.umd.prod.js +1 -1
  10. package/dist/icon-set/fontawesome-v7-pro.umd.prod.js +1 -1
  11. package/dist/icon-set/fontawesome-v7.umd.prod.js +1 -1
  12. package/dist/icon-set/ionicons-v4.umd.prod.js +1 -1
  13. package/dist/icon-set/line-awesome.umd.prod.js +1 -1
  14. package/dist/icon-set/material-icons-outlined.umd.prod.js +1 -1
  15. package/dist/icon-set/material-icons-round.umd.prod.js +1 -1
  16. package/dist/icon-set/material-icons-sharp.umd.prod.js +1 -1
  17. package/dist/icon-set/material-icons.umd.prod.js +1 -1
  18. package/dist/icon-set/material-symbols-outlined.umd.prod.js +1 -1
  19. package/dist/icon-set/material-symbols-rounded.umd.prod.js +1 -1
  20. package/dist/icon-set/material-symbols-sharp.umd.prod.js +1 -1
  21. package/dist/icon-set/mdi-v3.umd.prod.js +1 -1
  22. package/dist/icon-set/mdi-v4.umd.prod.js +1 -1
  23. package/dist/icon-set/mdi-v5.umd.prod.js +1 -1
  24. package/dist/icon-set/mdi-v6.umd.prod.js +1 -1
  25. package/dist/icon-set/mdi-v7.umd.prod.js +1 -1
  26. package/dist/icon-set/svg-bootstrap-icons.umd.prod.js +1 -1
  27. package/dist/icon-set/svg-eva-icons.umd.prod.js +1 -1
  28. package/dist/icon-set/svg-fontawesome-v5.umd.prod.js +1 -1
  29. package/dist/icon-set/svg-fontawesome-v6.umd.prod.js +1 -1
  30. package/dist/icon-set/svg-fontawesome-v7.umd.prod.js +1 -1
  31. package/dist/icon-set/svg-ionicons-v4.umd.prod.js +1 -1
  32. package/dist/icon-set/svg-ionicons-v5.umd.prod.js +1 -1
  33. package/dist/icon-set/svg-ionicons-v6.umd.prod.js +1 -1
  34. package/dist/icon-set/svg-ionicons-v7.umd.prod.js +1 -1
  35. package/dist/icon-set/svg-ionicons-v8.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-mdi-v7.umd.prod.js +1 -1
  46. package/dist/icon-set/svg-themify.umd.prod.js +1 -1
  47. package/dist/icon-set/themify.umd.prod.js +1 -1
  48. package/dist/lang/ar-TN.umd.prod.js +1 -1
  49. package/dist/lang/ar.umd.prod.js +1 -1
  50. package/dist/lang/az-Latn.umd.prod.js +2 -2
  51. package/dist/lang/bg.umd.prod.js +2 -2
  52. package/dist/lang/bn.umd.prod.js +2 -2
  53. package/dist/lang/bs-BA.umd.prod.js +2 -2
  54. package/dist/lang/ca.umd.prod.js +2 -2
  55. package/dist/lang/cs.umd.prod.js +2 -2
  56. package/dist/lang/da.umd.prod.js +2 -2
  57. package/dist/lang/de-CH.umd.prod.js +2 -2
  58. package/dist/lang/de-DE.umd.prod.js +2 -2
  59. package/dist/lang/de.umd.prod.js +2 -2
  60. package/dist/lang/el.umd.prod.js +2 -2
  61. package/dist/lang/en-GB.umd.prod.js +2 -2
  62. package/dist/lang/en-US.umd.prod.js +2 -2
  63. package/dist/lang/eo.umd.prod.js +2 -2
  64. package/dist/lang/es.umd.prod.js +2 -2
  65. package/dist/lang/et.umd.prod.js +2 -2
  66. package/dist/lang/eu.umd.prod.js +2 -2
  67. package/dist/lang/fa-IR.umd.prod.js +1 -1
  68. package/dist/lang/fa.umd.prod.js +1 -1
  69. package/dist/lang/fi.umd.prod.js +2 -2
  70. package/dist/lang/fr.umd.prod.js +2 -2
  71. package/dist/lang/gn.umd.prod.js +2 -2
  72. package/dist/lang/he.umd.prod.js +1 -1
  73. package/dist/lang/hi.umd.prod.js +2 -2
  74. package/dist/lang/hr.umd.prod.js +2 -2
  75. package/dist/lang/hu.umd.prod.js +2 -2
  76. package/dist/lang/id.umd.prod.js +2 -2
  77. package/dist/lang/is.umd.prod.js +2 -2
  78. package/dist/lang/it.umd.prod.js +2 -2
  79. package/dist/lang/ja.umd.prod.js +2 -2
  80. package/dist/lang/kk.umd.prod.js +2 -2
  81. package/dist/lang/km.umd.prod.js +2 -2
  82. package/dist/lang/ko-KR.umd.prod.js +1 -1
  83. package/dist/lang/kur-CKB.umd.prod.js +1 -1
  84. package/dist/lang/lb.umd.prod.js +2 -2
  85. package/dist/lang/lt.umd.prod.js +2 -2
  86. package/dist/lang/lu.umd.prod.js +2 -2
  87. package/dist/lang/lv.umd.prod.js +2 -2
  88. package/dist/lang/mk.umd.prod.js +2 -2
  89. package/dist/lang/ml.umd.prod.js +2 -2
  90. package/dist/lang/mm.umd.prod.js +2 -2
  91. package/dist/lang/ms-MY.umd.prod.js +2 -2
  92. package/dist/lang/ms.umd.prod.js +2 -2
  93. package/dist/lang/my.umd.prod.js +1 -1
  94. package/dist/lang/nb-NO.umd.prod.js +2 -2
  95. package/dist/lang/nl.umd.prod.js +2 -2
  96. package/dist/lang/pl.umd.prod.js +2 -2
  97. package/dist/lang/pt-BR.umd.prod.js +2 -2
  98. package/dist/lang/pt.umd.prod.js +2 -2
  99. package/dist/lang/ro.umd.prod.js +2 -2
  100. package/dist/lang/ru.umd.prod.js +2 -2
  101. package/dist/lang/sk.umd.prod.js +2 -2
  102. package/dist/lang/sl.umd.prod.js +2 -2
  103. package/dist/lang/sm.umd.prod.js +2 -2
  104. package/dist/lang/sq.umd.prod.js +2 -2
  105. package/dist/lang/sr-CYR.umd.prod.js +2 -2
  106. package/dist/lang/sr.umd.prod.js +2 -2
  107. package/dist/lang/sv.umd.prod.js +2 -2
  108. package/dist/lang/ta.umd.prod.js +2 -2
  109. package/dist/lang/th.umd.prod.js +2 -2
  110. package/dist/lang/tl.umd.prod.js +2 -2
  111. package/dist/lang/tr.umd.prod.js +2 -2
  112. package/dist/lang/ug.umd.prod.js +1 -1
  113. package/dist/lang/uk.umd.prod.js +2 -2
  114. package/dist/lang/ur-PK.umd.prod.js +1 -1
  115. package/dist/lang/uz-Cyrl.umd.prod.js +2 -2
  116. package/dist/lang/uz-Latn.umd.prod.js +2 -2
  117. package/dist/lang/vi.umd.prod.js +2 -2
  118. package/dist/lang/zh-CN.umd.prod.js +2 -2
  119. package/dist/lang/zh-TW.umd.prod.js +2 -2
  120. package/dist/quasar.client.js +573 -188
  121. package/dist/quasar.css +4 -0
  122. package/dist/quasar.prod.css +1 -1
  123. package/dist/quasar.rtl.css +5 -0
  124. package/dist/quasar.rtl.prod.css +1 -1
  125. package/dist/quasar.sass +4 -1
  126. package/dist/quasar.server.prod.cjs +35 -35
  127. package/dist/quasar.server.prod.js +25 -25
  128. package/dist/quasar.umd.js +573 -188
  129. package/dist/quasar.umd.prod.js +30 -30
  130. package/dist/types/composables.d.ts +10 -5
  131. package/dist/types/index.d.ts +4 -4
  132. package/dist/web-types/web-types.json +1 -1
  133. package/lang/az-Latn.js +1 -1
  134. package/lang/bg.js +1 -1
  135. package/lang/bn.js +1 -1
  136. package/lang/bs-BA.js +1 -1
  137. package/lang/ca.js +1 -1
  138. package/lang/cs.js +1 -1
  139. package/lang/da.js +1 -1
  140. package/lang/de-CH.js +1 -1
  141. package/lang/de-DE.js +1 -1
  142. package/lang/de.js +1 -1
  143. package/lang/el.js +1 -1
  144. package/lang/en-GB.js +1 -1
  145. package/lang/en-US.js +1 -1
  146. package/lang/eo.js +1 -1
  147. package/lang/es.js +1 -1
  148. package/lang/et.js +1 -1
  149. package/lang/eu.js +1 -1
  150. package/lang/fi.js +1 -1
  151. package/lang/fr.js +1 -1
  152. package/lang/gn.js +1 -1
  153. package/lang/hi.js +1 -1
  154. package/lang/hr.js +1 -1
  155. package/lang/hu.js +1 -1
  156. package/lang/id.js +1 -1
  157. package/lang/is.js +1 -1
  158. package/lang/it.js +1 -1
  159. package/lang/ja.js +1 -1
  160. package/lang/kk.js +1 -1
  161. package/lang/km.js +1 -1
  162. package/lang/lb.js +1 -1
  163. package/lang/lt.js +1 -1
  164. package/lang/lu.js +1 -1
  165. package/lang/lv.js +1 -1
  166. package/lang/mk.js +1 -1
  167. package/lang/ml.js +1 -1
  168. package/lang/mm.js +1 -1
  169. package/lang/ms-MY.js +1 -1
  170. package/lang/ms.js +1 -1
  171. package/lang/nb-NO.js +1 -1
  172. package/lang/nl.js +1 -1
  173. package/lang/pl.js +1 -1
  174. package/lang/pt-BR.js +1 -1
  175. package/lang/pt.js +1 -1
  176. package/lang/ro.js +1 -1
  177. package/lang/ru.js +1 -1
  178. package/lang/sk.js +1 -1
  179. package/lang/sl.js +1 -1
  180. package/lang/sm.js +1 -1
  181. package/lang/sq.js +1 -1
  182. package/lang/sr-CYR.js +1 -1
  183. package/lang/sr.js +1 -1
  184. package/lang/sv.js +1 -1
  185. package/lang/ta.js +1 -1
  186. package/lang/th.js +1 -1
  187. package/lang/tl.js +1 -1
  188. package/lang/tr.js +1 -1
  189. package/lang/uk.js +1 -1
  190. package/lang/uz-Cyrl.js +1 -1
  191. package/lang/uz-Latn.js +1 -1
  192. package/lang/vi.js +1 -1
  193. package/lang/zh-CN.js +1 -1
  194. package/lang/zh-TW.js +1 -1
  195. package/package.json +6 -6
  196. package/src/components/carousel/QCarousel.js +2 -0
  197. package/src/components/chip/QChip.js +20 -4
  198. package/src/components/date/QDate.js +9 -2
  199. package/src/components/dialog/QDialog.js +9 -2
  200. package/src/components/editor/QEditor.js +18 -3
  201. package/src/components/expansion-item/QExpansionItem.js +6 -1
  202. package/src/components/input/QInput.js +42 -1
  203. package/src/components/input/QInput.json +7 -0
  204. package/src/components/input/use-mask.js +12 -4
  205. package/src/components/item/QItem.js +10 -1
  206. package/src/components/menu/QMenu.js +9 -2
  207. package/src/components/range/QRange.js +2 -1
  208. package/src/components/rating/QRating.js +27 -8
  209. package/src/components/rating/QRating.sass +4 -0
  210. package/src/components/resize-observer/QResizeObserver.js +14 -3
  211. package/src/components/scroll-area/QScrollArea.js +69 -17
  212. package/src/components/slide-item/QSlideItem.js +3 -2
  213. package/src/components/slider/use-slider.js +7 -3
  214. package/src/components/stepper/StepHeader.js +11 -2
  215. package/src/components/table/QTable.js +11 -9
  216. package/src/components/table/QTh.js +20 -1
  217. package/src/components/table/table-column-selection.js +9 -1
  218. package/src/components/table/table-pagination.js +5 -2
  219. package/src/components/table/table-row-selection.js +10 -10
  220. package/src/components/tabs/QTabs.js +5 -6
  221. package/src/components/time/QTime.js +35 -10
  222. package/src/components/tooltip/QTooltip.js +112 -6
  223. package/src/components/tree/QTree.js +124 -4
  224. package/src/components/uploader/uploader-core.js +19 -4
  225. package/src/components/uploader/xhr-uploader-plugin.js +93 -43
  226. package/src/components/uploader/xhr-uploader-plugin.json +4 -4
  227. package/src/composables/private.use-field/use-field.js +2 -0
  228. package/src/composables/private.use-file/use-file.js +21 -12
  229. package/src/composables/private.use-fullscreen/use-fullscreen.js +8 -3
  230. package/src/composables/private.use-model-toggle/use-model-toggle.js +2 -0
  231. package/src/composables/private.use-panel/use-panel.js +6 -2
  232. package/src/composables/use-interval/use-interval.js +8 -0
  233. package/src/composables/use-render-cache/use-render-cache.js +15 -10
  234. package/src/composables/use-timeout/use-timeout.js +8 -0
  235. package/src/directives/intersection/Intersection.js +2 -2
  236. package/src/directives/touch-repeat/TouchRepeat.js +3 -1
  237. package/src/plugins/cookies/Cookies.js +29 -13
  238. package/src/plugins/lang/Lang.json +4 -4
  239. package/src/plugins/lang/Lang.test.js +1 -1
  240. package/src/plugins/meta/Meta.js +57 -9
  241. package/src/utils/extend/extend.js +4 -0
  242. package/src/utils/extend/extend.test.js +29 -0
  243. package/src/utils/scroll/prevent-scroll.js +4 -4
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Quasar Framework v2.21.3
2
+ * Quasar Framework v2.22.0
3
3
  * (c) 2015-present Razvan Stoenescu
4
4
  * Released under the MIT License.
5
5
  */
@@ -706,7 +706,7 @@
706
706
  selectedRecords: (rows) => rows === 1 ? "1 record selected." : (rows === 0 ? "No" : rows) + " records selected.",
707
707
  recordsPerPage: "Records per page:",
708
708
  allRows: "All",
709
- pagination: (start, end, total) => start + " - " + end + " of " + total,
709
+ pagination: (start, end, total) => start + "" + end + " of " + total,
710
710
  columns: "Columns"
711
711
  },
712
712
  pagination: {
@@ -1101,7 +1101,7 @@
1101
1101
  };
1102
1102
  }
1103
1103
  var install_quasar_default = function installQuasar(parentApp, opts = {}) {
1104
- const $q = { version: "2.21.3" };
1104
+ const $q = { version: "2.22.0" };
1105
1105
  if (!globalConfigIsFrozen) {
1106
1106
  if (opts.config !== void 0) Object.assign(globalConfig, opts.config);
1107
1107
  $q.config = { ...globalConfig };
@@ -2771,7 +2771,7 @@
2771
2771
  "beforeHide",
2772
2772
  "hide"
2773
2773
  ];
2774
- function useModelToggle({ showing, canShow, hideOnRouteChange, handleShow, handleHide, processOnMount }) {
2774
+ function useModelToggle({ showing, canShow, hideOnRouteChange, handleShow, handleHide, handleRouteChange, processOnMount }) {
2775
2775
  const vm = (0, vue.getCurrentInstance)();
2776
2776
  const { props, emit, proxy } = vm;
2777
2777
  let payload;
@@ -2824,7 +2824,10 @@
2824
2824
  }
2825
2825
  (0, vue.watch)(() => props.modelValue, processModelChange);
2826
2826
  if (hideOnRouteChange !== void 0 && vmHasRouter(vm)) (0, vue.watch)(() => proxy.$route.fullPath, () => {
2827
- if (hideOnRouteChange.value && showing.value) hide();
2827
+ if (hideOnRouteChange.value && showing.value) {
2828
+ handleRouteChange?.();
2829
+ hide();
2830
+ }
2828
2831
  });
2829
2832
  if (processOnMount) (0, vue.onMounted)(() => {
2830
2833
  processModelChange(props.modelValue);
@@ -3625,6 +3628,7 @@
3625
3628
  canShow,
3626
3629
  handleShow,
3627
3630
  handleHide,
3631
+ handleRouteChange,
3628
3632
  hideOnRouteChange,
3629
3633
  processOnMount: true
3630
3634
  });
@@ -3700,14 +3704,20 @@
3700
3704
  hidePortal();
3701
3705
  anchorCleanup(true);
3702
3706
  if (refocusTarget !== null && (evt === void 0 || !evt.qClickOutside)) {
3703
- ((evt?.type.indexOf("key") === 0 ? refocusTarget.closest("[tabindex]:not([tabindex^=\"-\"])") : void 0) || refocusTarget).focus();
3707
+ const target = (evt?.type.indexOf("key") === 0 ? refocusTarget.closest("[tabindex]:not([tabindex^=\"-\"])") : void 0) || refocusTarget;
3704
3708
  refocusTarget = null;
3709
+ addFocusFn(() => {
3710
+ if (target.isConnected) target.focus();
3711
+ });
3705
3712
  }
3706
3713
  registerTimeout(() => {
3707
3714
  hidePortal(true);
3708
3715
  emit("hide", evt);
3709
3716
  }, props.transitionDuration);
3710
3717
  }
3718
+ function handleRouteChange() {
3719
+ refocusTarget = null;
3720
+ }
3711
3721
  function anchorCleanup(hiding) {
3712
3722
  absoluteOffset = void 0;
3713
3723
  if (unwatchPosition !== void 0) {
@@ -4421,7 +4431,7 @@
4421
4431
  function useRenderCache() {
4422
4432
  let cache = Object.create(null);
4423
4433
  return {
4424
- getCache: (key, defaultValue) => cache[key] === void 0 ? cache[key] = typeof defaultValue === "function" ? defaultValue() : defaultValue : cache[key],
4434
+ getCache: (key, defaultValue) => Object.hasOwn(cache, key) ? cache[key] : cache[key] = typeof defaultValue === "function" ? defaultValue() : defaultValue,
4425
4435
  setCache(key, obj) {
4426
4436
  cache[key] = obj;
4427
4437
  },
@@ -4500,8 +4510,8 @@
4500
4510
  mouse: true
4501
4511
  }
4502
4512
  ]]);
4503
- const transitionPrev = (0, vue.computed)(() => props.transitionPrev || `slide-${props.vertical ? "down" : "right"}`);
4504
- const transitionNext = (0, vue.computed)(() => props.transitionNext || `slide-${props.vertical ? "up" : "left"}`);
4513
+ const transitionPrev = (0, vue.computed)(() => props.transitionPrev || `slide-${props.vertical ? "down" : proxy.$q.lang.rtl ? "left" : "right"}`);
4514
+ const transitionNext = (0, vue.computed)(() => props.transitionNext || `slide-${props.vertical ? "up" : proxy.$q.lang.rtl ? "right" : "left"}`);
4505
4515
  const transitionStyle = (0, vue.computed)(() => `--q-transition-duration: ${props.transitionDuration}ms`);
4506
4516
  const contentKey = (0, vue.computed)(() => typeof props.modelValue === "string" || typeof props.modelValue === "number" ? props.modelValue : String(props.modelValue));
4507
4517
  const keepAliveProps = (0, vue.computed)(() => ({
@@ -4621,7 +4631,7 @@
4621
4631
  function useFullscreen() {
4622
4632
  const vm = (0, vue.getCurrentInstance)();
4623
4633
  const { props, emit, proxy } = vm;
4624
- let historyEntry, fullscreenFillerNode;
4634
+ let historyEntry, fullscreenFillerNode, isUnmounting = false;
4625
4635
  const inFullscreen = (0, vue.ref)(false);
4626
4636
  if (vmHasRouter(vm)) (0, vue.watch)(() => proxy.$route.fullPath, () => {
4627
4637
  if (!props.noRouteFullscreenExit) exitFullscreen();
@@ -4658,7 +4668,7 @@
4658
4668
  counter = Math.max(0, counter - 1);
4659
4669
  if (counter === 0) {
4660
4670
  document.body.classList.remove("q-body--fullscreen-mixin");
4661
- if (proxy.$el.scrollIntoView !== void 0) setTimeout(() => {
4671
+ if (!isUnmounting && proxy.$el.scrollIntoView !== void 0) setTimeout(() => {
4662
4672
  proxy.$el.scrollIntoView();
4663
4673
  }, 0);
4664
4674
  }
@@ -4669,7 +4679,10 @@
4669
4679
  (0, vue.onMounted)(() => {
4670
4680
  if (props.fullscreen) setFullscreen();
4671
4681
  });
4672
- (0, vue.onBeforeUnmount)(exitFullscreen);
4682
+ (0, vue.onBeforeUnmount)(() => {
4683
+ isUnmounting = true;
4684
+ exitFullscreen();
4685
+ });
4673
4686
  Object.assign(proxy, {
4674
4687
  toggleFullscreen,
4675
4688
  setFullscreen,
@@ -4736,7 +4749,7 @@
4736
4749
  const { proxy: { $q } } = (0, vue.getCurrentInstance)();
4737
4750
  const isDark = useDark(props, $q);
4738
4751
  let timer = null, panelsLen;
4739
- const { updatePanelsList, getPanelContent, panelDirectives, goToPanel, previousPanel, nextPanel, getEnabledPanels, panelIndex } = usePanel();
4752
+ const { updatePanelsList, updatePanelIndex, getPanelContent, panelDirectives, goToPanel, previousPanel, nextPanel, getEnabledPanels, panelIndex } = usePanel();
4740
4753
  const { inFullscreen } = useFullscreen();
4741
4754
  const style = (0, vue.computed)(() => !inFullscreen.value && props.height !== void 0 ? { height: props.height } : {});
4742
4755
  const direction = (0, vue.computed)(() => props.vertical ? "vertical" : "horizontal");
@@ -4847,6 +4860,7 @@
4847
4860
  }
4848
4861
  return () => {
4849
4862
  panelsLen = updatePanelsList(slots);
4863
+ updatePanelIndex();
4850
4864
  return (0, vue.h)("div", {
4851
4865
  class: classes.value,
4852
4866
  style: style.value
@@ -5171,6 +5185,9 @@
5171
5185
  });
5172
5186
  //#endregion
5173
5187
  //#region src/components/chip/QChip.js
5188
+ function preventSpace$3(e) {
5189
+ if (e.keyCode === 32) stopAndPrevent(e);
5190
+ }
5174
5191
  const defaultSizes$1 = {
5175
5192
  xs: 8,
5176
5193
  sm: 10,
@@ -5233,7 +5250,11 @@
5233
5250
  const chip = props.disable ? {
5234
5251
  tabindex: -1,
5235
5252
  "aria-disabled": "true"
5236
- } : { tabindex: props.tabindex || 0 };
5253
+ } : {
5254
+ tabindex: props.tabindex || 0,
5255
+ role: "button",
5256
+ "aria-pressed": props.selected ? "true" : "false"
5257
+ };
5237
5258
  return {
5238
5259
  chip,
5239
5260
  remove: {
@@ -5245,7 +5266,10 @@
5245
5266
  };
5246
5267
  });
5247
5268
  function onKeyup(e) {
5248
- if (e.keyCode === 13) onClick(e);
5269
+ if ([13, 32].includes(e.keyCode)) {
5270
+ onClick(e);
5271
+ stopAndPrevent(e);
5272
+ }
5249
5273
  }
5250
5274
  function onClick(e) {
5251
5275
  if (!props.disable) {
@@ -5254,7 +5278,7 @@
5254
5278
  }
5255
5279
  }
5256
5280
  function onRemove(e) {
5257
- if (e.keyCode === void 0 || e.keyCode === 13) {
5281
+ if (e.keyCode === void 0 || [13, 32].includes(e.keyCode)) {
5258
5282
  stopAndPrevent(e);
5259
5283
  if (!props.disable) {
5260
5284
  emit("update:modelValue", false);
@@ -5280,6 +5304,7 @@
5280
5304
  name: removeIcon.value,
5281
5305
  ...attributes.value.remove,
5282
5306
  onClick: onRemove,
5307
+ onKeydown: preventSpace$3,
5283
5308
  onKeyup: onRemove
5284
5309
  }));
5285
5310
  return child;
@@ -5292,6 +5317,7 @@
5292
5317
  };
5293
5318
  if (isClickable.value) Object.assign(data, attributes.value.chip, {
5294
5319
  onClick,
5320
+ onKeydown: preventSpace$3,
5295
5321
  onKeyup
5296
5322
  });
5297
5323
  return hDir("div", data, getContent(), "ripple", props.ripple !== false && !props.disable, () => [[Ripple_default, props.ripple]]);
@@ -6054,16 +6080,14 @@
6054
6080
  viewBox: "0 0 20 20",
6055
6081
  "aria-hidden": "true"
6056
6082
  }, [(0, vue.h)("path", { d: props.thumbPath })]), (0, vue.h)("div", { class: "q-slider__focus-ring fit" })];
6057
- if (props.label || props.labelAlways) {
6058
- thumbContent.push((0, vue.h)("div", { class: pinClass.value + " absolute fit no-pointer-events" + pinColor.value }, [(0, vue.h)("div", {
6059
- class: labelClass.value,
6060
- style: { minWidth: props.thumbSize }
6061
- }, [(0, vue.h)("div", {
6062
- class: textContainerClass.value,
6063
- style: textContainerStyle.value
6064
- }, [(0, vue.h)("span", { class: textClass.value }, thumb.label.value)])])]));
6065
- if (props.name !== void 0 && !props.disable) injectFormInput(thumbContent, "push");
6066
- }
6083
+ if (props.label || props.labelAlways) thumbContent.push((0, vue.h)("div", { class: pinClass.value + " absolute fit no-pointer-events" + pinColor.value }, [(0, vue.h)("div", {
6084
+ class: labelClass.value,
6085
+ style: { minWidth: props.thumbSize }
6086
+ }, [(0, vue.h)("div", {
6087
+ class: textContainerClass.value,
6088
+ style: textContainerStyle.value
6089
+ }, [(0, vue.h)("span", { class: textClass.value }, thumb.label.value)])])]));
6090
+ if (thumb.injectFormInput !== false && props.name !== void 0 && !props.disable) injectFormInput(thumbContent, "push");
6067
6091
  return (0, vue.h)("div", {
6068
6092
  class: thumbClasses.value,
6069
6093
  style: style.value,
@@ -6290,8 +6314,9 @@
6290
6314
  const { proxy } = (0, vue.getCurrentInstance)();
6291
6315
  proxy.trigger = trigger;
6292
6316
  if (hasObserver) {
6293
- let observer;
6317
+ let observer, isDestroyed = false;
6294
6318
  const init = (stop) => {
6319
+ if (isDestroyed) return;
6295
6320
  targetEl = proxy.$el.parentNode;
6296
6321
  if (targetEl) {
6297
6322
  observer = new ResizeObserver(trigger);
@@ -6305,6 +6330,7 @@
6305
6330
  init();
6306
6331
  });
6307
6332
  (0, vue.onBeforeUnmount)(() => {
6333
+ isDestroyed = true;
6308
6334
  if (timer !== null) clearTimeout(timer);
6309
6335
  if (observer !== void 0) {
6310
6336
  if (observer.disconnect !== void 0) observer.disconnect();
@@ -6314,7 +6340,7 @@
6314
6340
  return noop;
6315
6341
  }
6316
6342
  const { isHydrated } = useHydration();
6317
- let curDocView;
6343
+ let curDocView, isDestroyed = false;
6318
6344
  const cleanup = () => {
6319
6345
  if (timer !== null) {
6320
6346
  clearTimeout(timer);
@@ -6335,11 +6361,15 @@
6335
6361
  };
6336
6362
  (0, vue.onMounted)(() => {
6337
6363
  (0, vue.nextTick)(() => {
6364
+ if (isDestroyed) return;
6338
6365
  targetEl = proxy.$el;
6339
6366
  if (targetEl) onObjLoad();
6340
6367
  });
6341
6368
  });
6342
- (0, vue.onBeforeUnmount)(cleanup);
6369
+ (0, vue.onBeforeUnmount)(() => {
6370
+ isDestroyed = true;
6371
+ cleanup();
6372
+ });
6343
6373
  return () => {
6344
6374
  if (isHydrated.value) return (0, vue.h)("object", {
6345
6375
  class: "q--avoid-card-border",
@@ -6592,12 +6622,10 @@
6592
6622
  const dirNext = keyCode === (props.vertical ? 40 : 39);
6593
6623
  const dir = dirPrev ? -1 : dirNext ? 1 : void 0;
6594
6624
  if (dir !== void 0) {
6595
- const rtlDir = isRTL.value ? -1 : 1;
6596
- const index = tabs.indexOf(fromEl) + dir * rtlDir;
6597
- if (index >= 0 && index < len) {
6598
- scrollToTabEl(tabs[index]);
6599
- tabs[index].focus({ preventScroll: true });
6600
- }
6625
+ const rtlDir = props.vertical !== true && isRTL.value ? -1 : 1;
6626
+ const index = (tabs.indexOf(fromEl) + dir * rtlDir + len) % len;
6627
+ scrollToTabEl(tabs[index]);
6628
+ tabs[index].focus({ preventScroll: true });
6601
6629
  return true;
6602
6630
  }
6603
6631
  }
@@ -6772,6 +6800,7 @@
6772
6800
  ref: rootRef,
6773
6801
  class: classes.value,
6774
6802
  role: "tablist",
6803
+ "aria-orientation": props.vertical ? "vertical" : "horizontal",
6775
6804
  onFocusin,
6776
6805
  onFocusout
6777
6806
  }, [
@@ -8728,6 +8757,7 @@
8728
8757
  const { $q } = proxy;
8729
8758
  const isDark = useDark(props, $q);
8730
8759
  const { getCache } = useRenderCache();
8760
+ const { isHydrated } = useHydration();
8731
8761
  const { tabindex, headerClass, getLocale, getCurrentDate } = useDatetime(props, $q);
8732
8762
  let lastEmitValue;
8733
8763
  const injectFormInput = useFormInject(useFormAttrs(props));
@@ -9041,7 +9071,7 @@
9041
9071
  if (rangeView.value.includeFrom) res[from].editRangeFrom = true;
9042
9072
  if (rangeView.value.includeTo) res[to].editRangeTo = true;
9043
9073
  }
9044
- if (viewModel.value.year === today.value.year && viewModel.value.month === today.value.month) res[index + today.value.day - 1].today = true;
9074
+ if (isHydrated.value && viewModel.value.year === today.value.year && viewModel.value.month === today.value.month) res[index + today.value.day - 1].today = true;
9045
9075
  const left = res.length % 7;
9046
9076
  if (left > 0) {
9047
9077
  const afterDays = 7 - left;
@@ -9432,7 +9462,7 @@
9432
9462
  }, day.event ? () => (0, vue.h)("div", { class: "q-date__event bg-" + day.event }) : null) : (0, vue.h)("div", String(day.i))]))))])
9433
9463
  ])],
9434
9464
  Months() {
9435
- const currentYear = viewModel.value.year === today.value.year;
9465
+ const currentYear = isHydrated.value && viewModel.value.year === today.value.year;
9436
9466
  const isDisabled = (month) => minNav.value !== null && viewModel.value.year === minNav.value.year && minNav.value.month > month || maxNav.value !== null && viewModel.value.year === maxNav.value.year && maxNav.value.month < month;
9437
9467
  const content = innerLocale.value.monthsShort.map((month, i) => {
9438
9468
  const active = viewModel.value.month === i + 1;
@@ -9471,7 +9501,7 @@
9471
9501
  const active = viewModel.value.year === i;
9472
9502
  years.push((0, vue.h)("div", { class: "q-date__years-item flex flex-center" }, [(0, vue.h)(QBtn_default, {
9473
9503
  key: "yr" + i,
9474
- class: today.value.year === i ? "q-date__today" : null,
9504
+ class: isHydrated.value && today.value.year === i ? "q-date__today" : null,
9475
9505
  flat: !active,
9476
9506
  label: i,
9477
9507
  dense: true,
@@ -9632,7 +9662,7 @@
9632
9662
  let vpPendingUpdate = false;
9633
9663
  let bodyLeft;
9634
9664
  let bodyTop;
9635
- let href;
9665
+ let routePath;
9636
9666
  let closeTimer = null;
9637
9667
  function onAppleScroll(e) {
9638
9668
  if (e.target === document) document.scrollingElement.scrollTop = document.scrollingElement.scrollTop;
@@ -9658,7 +9688,7 @@
9658
9688
  scrollPositionY = getVerticalScrollPosition(window);
9659
9689
  bodyLeft = body.style.left;
9660
9690
  bodyTop = body.style.top;
9661
- href = window.location.href;
9691
+ routePath = window.location.pathname;
9662
9692
  body.style.left = `-${scrollPositionX}px`;
9663
9693
  body.style.top = `-${scrollPositionY}px`;
9664
9694
  if (overflowX !== "hidden" && (overflowX === "scroll" || body.scrollWidth > window.innerWidth)) body.classList.add("q-body--force-scrollbar-x");
@@ -9681,7 +9711,7 @@
9681
9711
  document.qScrollPrevented = false;
9682
9712
  body.style.left = bodyLeft;
9683
9713
  body.style.top = bodyTop;
9684
- if (window.location.href === href) window.scrollTo(scrollPositionX, scrollPositionY);
9714
+ if (window.location.pathname === routePath) window.scrollTo(scrollPositionX, scrollPositionY);
9685
9715
  maxScrollTop = void 0;
9686
9716
  }
9687
9717
  }
@@ -9798,6 +9828,7 @@
9798
9828
  hideOnRouteChange,
9799
9829
  handleShow,
9800
9830
  handleHide,
9831
+ handleRouteChange,
9801
9832
  processOnMount: true
9802
9833
  });
9803
9834
  const { addToHistory, removeFromHistory } = useHistory(showing, hide, hideOnRouteChange);
@@ -9852,8 +9883,11 @@
9852
9883
  animating.value = true;
9853
9884
  hidePortal();
9854
9885
  if (refocusTarget !== null) {
9855
- ((evt?.type.indexOf("key") === 0 ? refocusTarget.closest("[tabindex]:not([tabindex^=\"-\"])") : void 0) || refocusTarget).focus();
9886
+ const target = (evt?.type.indexOf("key") === 0 ? refocusTarget.closest("[tabindex]:not([tabindex^=\"-\"])") : void 0) || refocusTarget;
9856
9887
  refocusTarget = null;
9888
+ addFocusFn(() => {
9889
+ if (target.isConnected) target.focus();
9890
+ });
9857
9891
  }
9858
9892
  registerTimeout(() => {
9859
9893
  hidePortal(true);
@@ -9861,6 +9895,9 @@
9861
9895
  emit("hide", evt);
9862
9896
  }, props.transitionDuration);
9863
9897
  }
9898
+ function handleRouteChange() {
9899
+ refocusTarget = null;
9900
+ }
9864
9901
  function focus(selector) {
9865
9902
  addFocusFn(() => {
9866
9903
  let node = innerRef.value;
@@ -10588,6 +10625,7 @@
10588
10625
  };
10589
10626
  //#endregion
10590
10627
  //#region src/components/tooltip/QTooltip.js
10628
+ let nonSelectableCount = 0;
10591
10629
  var QTooltip_default = createComponent({
10592
10630
  name: "QTooltip",
10593
10631
  inheritAttrs: false,
@@ -10639,11 +10677,13 @@
10639
10677
  },
10640
10678
  emits: [...useModelToggleEmits],
10641
10679
  setup(props, { slots, emit, attrs }) {
10642
- let unwatchPosition, observer;
10680
+ let unwatchPosition, observer, removeNonSelectableTimer, hasNonSelectable = false, describedBy;
10643
10681
  const vm = (0, vue.getCurrentInstance)();
10644
10682
  const { proxy: { $q } } = vm;
10645
10683
  const innerRef = (0, vue.ref)(null);
10646
10684
  const showing = (0, vue.ref)(false);
10685
+ const targetUid = useId();
10686
+ const tooltipId = (0, vue.computed)(() => attrs.id || targetUid.value);
10647
10687
  const anchorOrigin = (0, vue.computed)(() => parsePosition(props.anchor, $q.lang.rtl));
10648
10688
  const selfOrigin = (0, vue.computed)(() => parsePosition(props.self, $q.lang.rtl));
10649
10689
  const hideOnRouteChange = (0, vue.computed)(() => !props.persistent);
@@ -10665,7 +10705,8 @@
10665
10705
  });
10666
10706
  Object.assign(anchorEvents, {
10667
10707
  delayShow,
10668
- delayHide
10708
+ delayHide,
10709
+ onFocusin
10669
10710
  });
10670
10711
  const { showPortal, hidePortal, renderPortal } = usePortal(vm, innerRef, renderPortalContent, "tooltip");
10671
10712
  if ($q.platform.is.mobile) {
@@ -10684,9 +10725,12 @@
10684
10725
  (0, vue.onBeforeUnmount)(() => {
10685
10726
  removeClickOutside(clickOutsideProps);
10686
10727
  });
10687
- }
10728
+ } else (0, vue.watch)(() => (props.modelValue === null || props["onUpdate:modelValue"]) && showing.value === true && props.persistent !== true, (val) => {
10729
+ (val === true ? addEscapeKey : removeEscapeKey)(onEscapeKey);
10730
+ });
10688
10731
  function handleShow(evt) {
10689
10732
  showPortal();
10733
+ addAriaDescription();
10690
10734
  registerTick(() => {
10691
10735
  observer?.disconnect();
10692
10736
  if (innerRef.value === null) {
@@ -10728,7 +10772,10 @@
10728
10772
  unwatchPosition = void 0;
10729
10773
  }
10730
10774
  unconfigureScrollTarget();
10775
+ removeEscapeKey(onEscapeKey);
10731
10776
  cleanEvt(anchorEvents, "tooltipTemp");
10777
+ removeAriaDescription();
10778
+ setNonSelectable(false);
10732
10779
  }
10733
10780
  function updatePosition() {
10734
10781
  setPosition({
@@ -10743,8 +10790,12 @@
10743
10790
  }
10744
10791
  function delayShow(evt) {
10745
10792
  if ($q.platform.is.mobile) {
10793
+ if (removeNonSelectableTimer !== void 0) {
10794
+ clearTimeout(removeNonSelectableTimer);
10795
+ removeNonSelectableTimer = void 0;
10796
+ }
10746
10797
  clearSelection();
10747
- document.body.classList.add("non-selectable");
10798
+ setNonSelectable(true);
10748
10799
  const target = anchorEl.value;
10749
10800
  const evts = [
10750
10801
  "touchmove",
@@ -10767,14 +10818,26 @@
10767
10818
  if ($q.platform.is.mobile) {
10768
10819
  cleanEvt(anchorEvents, "tooltipTemp");
10769
10820
  clearSelection();
10770
- setTimeout(() => {
10771
- document.body.classList.remove("non-selectable");
10821
+ removeNonSelectableTimer = setTimeout(() => {
10822
+ removeNonSelectableTimer = void 0;
10823
+ setNonSelectable(false);
10772
10824
  }, 10);
10773
10825
  }
10774
10826
  registerTimeout(() => {
10775
10827
  hide(evt);
10776
10828
  }, props.hideDelay);
10777
10829
  }
10830
+ function onFocusin(evt) {
10831
+ const el = evt.target;
10832
+ if (!el) return;
10833
+ try {
10834
+ if (el.matches(":focus-visible") === false) return;
10835
+ } catch {}
10836
+ delayShow(evt);
10837
+ }
10838
+ function onEscapeKey(evt) {
10839
+ hide(evt);
10840
+ }
10778
10841
  function configureAnchorEl() {
10779
10842
  if (props.noParentEvent || anchorEl.value === null) return;
10780
10843
  const evts = $q.platform.is.mobile ? [[
@@ -10782,19 +10845,66 @@
10782
10845
  "touchstart",
10783
10846
  "delayShow",
10784
10847
  "passive"
10785
- ]] : [[
10786
- anchorEl.value,
10787
- "mouseenter",
10788
- "delayShow",
10789
- "passive"
10790
- ], [
10791
- anchorEl.value,
10792
- "mouseleave",
10793
- "delayHide",
10794
- "passive"
10795
- ]];
10848
+ ]] : [
10849
+ [
10850
+ anchorEl.value,
10851
+ "mouseenter",
10852
+ "delayShow",
10853
+ "passive"
10854
+ ],
10855
+ [
10856
+ anchorEl.value,
10857
+ "mouseleave",
10858
+ "delayHide",
10859
+ "passive"
10860
+ ],
10861
+ [
10862
+ anchorEl.value,
10863
+ "focusin",
10864
+ "onFocusin",
10865
+ "passive"
10866
+ ],
10867
+ [
10868
+ anchorEl.value,
10869
+ "focusout",
10870
+ "delayHide",
10871
+ "passive"
10872
+ ]
10873
+ ];
10796
10874
  addEvt(anchorEvents, "anchor", evts);
10797
10875
  }
10876
+ function setNonSelectable(state) {
10877
+ if (hasNonSelectable === state) return;
10878
+ hasNonSelectable = state;
10879
+ nonSelectableCount += state ? 1 : -1;
10880
+ document.body.classList.toggle("non-selectable", nonSelectableCount > 0);
10881
+ if (!state && removeNonSelectableTimer !== void 0) {
10882
+ clearTimeout(removeNonSelectableTimer);
10883
+ removeNonSelectableTimer = void 0;
10884
+ }
10885
+ }
10886
+ function addAriaDescription() {
10887
+ const el = anchorEl.value, id = tooltipId.value;
10888
+ if (el === null || id === void 0) return;
10889
+ const ids = (el.getAttribute("aria-describedby") || "").split(/\s+/).filter(Boolean);
10890
+ describedBy = {
10891
+ el,
10892
+ id,
10893
+ added: !ids.includes(id)
10894
+ };
10895
+ if (describedBy.added) {
10896
+ ids.push(id);
10897
+ el.setAttribute("aria-describedby", ids.join(" "));
10898
+ }
10899
+ }
10900
+ function removeAriaDescription() {
10901
+ if (describedBy?.added === true) {
10902
+ const { el, id } = describedBy, value = (el.getAttribute("aria-describedby") || "").split(/\s+/).filter((entry) => entry !== "" && entry !== id);
10903
+ if (value.length === 0) el.removeAttribute("aria-describedby");
10904
+ else el.setAttribute("aria-describedby", value.join(" "));
10905
+ }
10906
+ describedBy = void 0;
10907
+ }
10798
10908
  function configureScrollTarget() {
10799
10909
  if (anchorEl.value !== null || props.scrollTarget !== void 0) {
10800
10910
  localScrollTarget.value = getScrollTarget(anchorEl.value, props.scrollTarget);
@@ -10805,6 +10915,7 @@
10805
10915
  function getTooltipContent() {
10806
10916
  return showing.value ? (0, vue.h)("div", {
10807
10917
  ...attrs,
10918
+ id: tooltipId.value,
10808
10919
  ref: innerRef,
10809
10920
  class: ["q-tooltip q-tooltip--style q-position-engine no-pointer-events", attrs.class],
10810
10921
  style: [attrs.style, transitionStyle.value],
@@ -10874,6 +10985,9 @@
10874
10985
  }
10875
10986
  emit("keyup", e);
10876
10987
  }
10988
+ function onKeydown(e) {
10989
+ if (isClickable.value && e.keyCode === 32) stopAndPrevent(e);
10990
+ }
10877
10991
  function getContent() {
10878
10992
  const child = hUniqueSlot(slots.default, []);
10879
10993
  if (isClickable.value) child.unshift((0, vue.h)("div", {
@@ -10888,8 +11002,9 @@
10888
11002
  ref: rootRef,
10889
11003
  class: classes.value,
10890
11004
  style: style.value,
10891
- role: "listitem",
11005
+ role: hasLink.value ? void 0 : isClickable.value ? "button" : "listitem",
10892
11006
  onClick,
11007
+ onKeydown,
10893
11008
  onKeyup
10894
11009
  };
10895
11010
  if (isClickable.value) {
@@ -11152,6 +11267,7 @@
11152
11267
  i--;
11153
11268
  }
11154
11269
  for (; i < length; i++) if ((options = args[i]) !== null) for (name in options) {
11270
+ if (name === "__proto__") continue;
11155
11271
  src = target[name];
11156
11272
  copy = options[name];
11157
11273
  if (target === copy) continue;
@@ -11254,8 +11370,9 @@
11254
11370
  const editLinkUrl = (0, vue.ref)(null);
11255
11371
  const isViewingSource = (0, vue.ref)(false);
11256
11372
  const editable = (0, vue.computed)(() => !props.readonly && !props.disable);
11257
- let defaultFont, offsetBottom;
11373
+ let defaultFont, offsetBottom, refreshToolbarTimer = null;
11258
11374
  let lastEmit = props.modelValue;
11375
+ const renderInitialContent = isRuntimeSsrPreHydration.value;
11259
11376
  document.execCommand("defaultParagraphSeparator", false, props.paragraphTag);
11260
11377
  defaultFont = window.getComputedStyle(document.body).fontFamily;
11261
11378
  const toolbarBackgroundClass = (0, vue.computed)(() => props.toolbarBg ? ` bg-${props.toolbarBg}` : "");
@@ -11686,7 +11803,9 @@
11686
11803
  });
11687
11804
  }
11688
11805
  function refreshToolbar() {
11689
- setTimeout(() => {
11806
+ if (refreshToolbarTimer !== null) clearTimeout(refreshToolbarTimer);
11807
+ refreshToolbarTimer = setTimeout(() => {
11808
+ refreshToolbarTimer = null;
11690
11809
  editLinkUrl.value = null;
11691
11810
  proxy.$forceUpdate();
11692
11811
  }, 1);
@@ -11706,6 +11825,7 @@
11706
11825
  document.addEventListener("selectionchange", onSelectionchange);
11707
11826
  });
11708
11827
  (0, vue.onBeforeUnmount)(() => {
11828
+ if (refreshToolbarTimer !== null) clearTimeout(refreshToolbarTimer);
11709
11829
  document.removeEventListener("selectionchange", onSelectionchange);
11710
11830
  });
11711
11831
  Object.assign(proxy, {
@@ -11743,6 +11863,7 @@
11743
11863
  class: innerClass.value,
11744
11864
  contenteditable: editable.value,
11745
11865
  placeholder: props.placeholder,
11866
+ ...renderInitialContent ? { innerHTML: props.modelValue } : {},
11746
11867
  ...splitAttrs.listeners.value,
11747
11868
  onInput,
11748
11869
  onKeydown,
@@ -11927,6 +12048,9 @@
11927
12048
  //#endregion
11928
12049
  //#region src/components/expansion-item/QExpansionItem.js
11929
12050
  const itemGroups = (0, vue.shallowReactive)({});
12051
+ function preventSpace$2(e) {
12052
+ if (e.keyCode === 32) stopAndPrevent(e);
12053
+ }
11930
12054
  const LINK_PROPS = Object.keys(useRouterLinkProps);
11931
12055
  var QExpansionItem_default = createComponent({
11932
12056
  name: "QExpansionItem",
@@ -12025,7 +12149,7 @@
12025
12149
  emit("click", e);
12026
12150
  }
12027
12151
  function toggleIconKeyboard(e) {
12028
- if (e.keyCode === 13) toggleIcon(e, true);
12152
+ if ([13, 32].includes(e.keyCode)) toggleIcon(e, true);
12029
12153
  }
12030
12154
  function toggleIcon(e, keyboard) {
12031
12155
  if (!keyboard && !e.qAvoidFocus) blurTargetRef.value?.focus();
@@ -12070,6 +12194,7 @@
12070
12194
  tabindex: 0,
12071
12195
  ...toggleAriaAttrs.value,
12072
12196
  onClick: toggleIcon,
12197
+ onKeydown: preventSpace$2,
12073
12198
  onKeyup: toggleIconKeyboard
12074
12199
  });
12075
12200
  child.unshift((0, vue.h)("div", {
@@ -12705,6 +12830,7 @@
12705
12830
  if (!$q.platform.is.mobile) (state.targetRef?.value || state.rootRef.value).focus();
12706
12831
  else if (state.rootRef.value.contains(document.activeElement)) document.activeElement.blur();
12707
12832
  if (props.type === "file") state.inputRef.value.value = null;
12833
+ state.onClear?.();
12708
12834
  emit("update:modelValue", null);
12709
12835
  if (state.changeEvent) emit("change", null);
12710
12836
  emit("clear", props.modelValue);
@@ -12915,7 +13041,7 @@
12915
13041
  if (rejectedFiles.length !== 0) emit("rejected", rejectedFiles);
12916
13042
  };
12917
13043
  if (props.accept !== void 0 && !extensions.value.includes("*/")) {
12918
- files = filterFiles(files, rejectedFiles, "accept", (file) => extensions.value.some((ext) => file.type.toUpperCase().startsWith(ext) || file.name.toUpperCase().endsWith(ext)));
13044
+ files = filterFiles(files, rejectedFiles, "accept", (file) => extensions.value.some((ext) => (ext.endsWith("/") ? file.type.toUpperCase().startsWith(ext) : file.type.toUpperCase() === ext) || file.name.toUpperCase().endsWith(ext)));
12919
13045
  if (files.length === 0) return done();
12920
13046
  }
12921
13047
  if (props.maxFileSize !== void 0) {
@@ -12925,18 +13051,29 @@
12925
13051
  }
12926
13052
  if (!props.multiple && files.length !== 0) files = [files[0]];
12927
13053
  files.forEach((file) => {
12928
- file.__key = file.webkitRelativePath + file.lastModified + file.name + file.size;
13054
+ file.__key = JSON.stringify([
13055
+ file.webkitRelativePath,
13056
+ file.lastModified,
13057
+ file.name,
13058
+ file.size
13059
+ ]);
12929
13060
  });
12930
13061
  if (append) {
12931
- const filenameMap = currentFileList.map((entry) => entry.__key);
12932
- files = filterFiles(files, rejectedFiles, "duplicate", (file) => !filenameMap.includes(file.__key));
13062
+ const filenameSet = new Set(currentFileList.map((entry) => entry.__key));
13063
+ files = filterFiles(files, rejectedFiles, "duplicate", (file) => {
13064
+ if (filenameSet.has(file.__key)) return false;
13065
+ filenameSet.add(file.__key);
13066
+ return true;
13067
+ });
12933
13068
  }
12934
13069
  if (files.length === 0) return done();
12935
13070
  if (props.maxTotalSize !== void 0) {
12936
13071
  let size = append ? currentFileList.reduce((total, file) => total + file.size, 0) : 0;
12937
13072
  files = filterFiles(files, rejectedFiles, "max-total-size", (file) => {
12938
- size += file.size;
12939
- return size <= maxTotalSizeNumber.value;
13073
+ const newSize = size + file.size;
13074
+ if (newSize > maxTotalSizeNumber.value) return false;
13075
+ size = newSize;
13076
+ return true;
12940
13077
  });
12941
13078
  if (files.length === 0) return done();
12942
13079
  }
@@ -14104,6 +14241,9 @@
14104
14241
  (0, vue.watch)(() => props.unmaskedValue, () => {
14105
14242
  if (hasMask.value) updateMaskValue(innerValue.value);
14106
14243
  });
14244
+ (0, vue.watch)(() => props.maskTokens, () => {
14245
+ if (hasMask.value) updateMaskValue(innerValue.value, true);
14246
+ }, { deep: true });
14107
14247
  function getInitialMaskedValue() {
14108
14248
  updateMaskInternals();
14109
14249
  if (hasMask.value) {
@@ -14177,12 +14317,12 @@
14177
14317
  maskReplaced = maskMarked.split(MARKER).join(fillChar);
14178
14318
  }
14179
14319
  function updateMaskValue(rawVal, updateMaskInternalsFlag, inputType) {
14180
- const inp = inputRef.value, end = inp.selectionEnd, endReverse = inp.value.length - end, unmasked = unmaskValue(rawVal);
14320
+ const inp = inputRef.value, end = inp?.selectionEnd ?? 0, endReverse = inp === null ? 0 : inp.value.length - end, unmasked = unmaskValue(rawVal);
14181
14321
  if (updateMaskInternalsFlag === true) updateMaskInternals();
14182
14322
  const preMasked = maskValue(unmasked, updateMaskInternalsFlag), masked = props.fillMask !== false ? fillWithMask(preMasked) : preMasked, changed = innerValue.value !== masked;
14183
- if (inp.value !== masked) inp.value = masked;
14323
+ if (inp !== null && inp.value !== masked) inp.value = masked;
14184
14324
  if (changed) innerValue.value = masked;
14185
- if (document.activeElement === inp) (0, vue.nextTick)(() => {
14325
+ if (inp !== null && document.activeElement === inp) (0, vue.nextTick)(() => {
14186
14326
  if (masked === maskReplaced) {
14187
14327
  const cursor = props.reverseFillMask ? maskReplaced.length : 0;
14188
14328
  inp.setSelectionRange(cursor, cursor, "forward");
@@ -14380,6 +14520,7 @@
14380
14520
  Number,
14381
14521
  FileList
14382
14522
  ],
14523
+ modelModifiers: Object,
14383
14524
  shadowText: String,
14384
14525
  type: {
14385
14526
  type: String,
@@ -14464,6 +14605,12 @@
14464
14605
  if (inputRef.value) inputRef.value.value = props.modelValue;
14465
14606
  });
14466
14607
  (0, vue.watch)(() => props.modelValue, (v) => {
14608
+ if (emitTimer !== null) {
14609
+ cancelPendingValueEmission();
14610
+ typedNumber = false;
14611
+ stopValueWatcher = false;
14612
+ delete temp.value;
14613
+ }
14467
14614
  if (hasMask.value) {
14468
14615
  if (stopValueWatcher) {
14469
14616
  stopValueWatcher = false;
@@ -14474,6 +14621,7 @@
14474
14621
  innerValue.value = v;
14475
14622
  if (props.type === "number" && Object.hasOwn(temp, "value")) if (typedNumber) typedNumber = false;
14476
14623
  else delete temp.value;
14624
+ if (props.modelModifiers?.trim === true && Object.hasOwn(temp, "value") && (typeof temp.value !== "string" || temp.value.trim() !== v)) delete temp.value;
14477
14625
  }
14478
14626
  if (props.autogrow) (0, vue.nextTick)(adjustHeight);
14479
14627
  });
@@ -14513,6 +14661,7 @@
14513
14661
  }
14514
14662
  if (hasMask.value) updateMaskValue(val, false, e.inputType);
14515
14663
  else {
14664
+ if (props.modelModifiers?.trim === true) temp.value = val;
14516
14665
  emitValue(val);
14517
14666
  if (isTypeText.value && e.target === document.activeElement) {
14518
14667
  const { selectionStart, selectionEnd } = e.target;
@@ -14530,7 +14679,7 @@
14530
14679
  function emitValue(val, stopWatcher) {
14531
14680
  emitValueFn = () => {
14532
14681
  emitTimer = null;
14533
- if (props.type !== "number" && Object.hasOwn(temp, "value")) delete temp.value;
14682
+ if (props.type !== "number" && (props.modelModifiers?.trim !== true || hasMask.value) && Object.hasOwn(temp, "value")) delete temp.value;
14534
14683
  if (props.modelValue !== val && emitCachedValue !== val) {
14535
14684
  emitCachedValue = val;
14536
14685
  if (stopWatcher === true) stopValueWatcher = true;
@@ -14551,6 +14700,19 @@
14551
14700
  emitTimer = setTimeout(emitValueFn, props.debounce);
14552
14701
  } else emitValueFn();
14553
14702
  }
14703
+ function cancelPendingValueEmission() {
14704
+ if (emitTimer !== null) {
14705
+ clearTimeout(emitTimer);
14706
+ emitTimer = null;
14707
+ }
14708
+ emitValueFn = void 0;
14709
+ }
14710
+ function onClear() {
14711
+ cancelPendingValueEmission();
14712
+ typedNumber = false;
14713
+ stopValueWatcher = false;
14714
+ delete temp.value;
14715
+ }
14554
14716
  function adjustHeight() {
14555
14717
  requestAnimationFrame(() => {
14556
14718
  const inp = inputRef.value;
@@ -14607,6 +14769,7 @@
14607
14769
  hasShadow: (0, vue.computed)(() => props.type !== "file" && typeof props.shadowText === "string" && props.shadowText.length !== 0),
14608
14770
  inputRef,
14609
14771
  emitValue,
14772
+ onClear,
14610
14773
  hasValue,
14611
14774
  floatingLabel: (0, vue.computed)(() => hasValue.value && (props.type !== "number" || Number.isFinite(Number(innerValue.value))) || fieldValueIsFilled(props.displayValue)),
14612
14775
  getControl: () => (0, vue.h)(isTextarea.value ? "textarea" : "input", {
@@ -14653,7 +14816,7 @@
14653
14816
  if (ctx.handler !== handler) ctx.handler = handler;
14654
14817
  if (changed) {
14655
14818
  ctx.cfg = cfg;
14656
- ctx.observer?.unobserve(el);
14819
+ ctx.observer?.disconnect();
14657
14820
  ctx.observer = new IntersectionObserver(([entry]) => {
14658
14821
  if (typeof ctx.handler === "function") {
14659
14822
  if (entry.rootBounds === null && document.body.contains(el)) {
@@ -14670,7 +14833,7 @@
14670
14833
  function destroy$1(el) {
14671
14834
  const ctx = el.__qvisible;
14672
14835
  if (ctx !== void 0) {
14673
- ctx.observer?.unobserve(el);
14836
+ ctx.observer?.disconnect();
14674
14837
  delete el.__qvisible;
14675
14838
  }
14676
14839
  }
@@ -16732,6 +16895,7 @@
16732
16895
  });
16733
16896
  const maxEvents = (0, vue.computed)(() => getEvents("max"));
16734
16897
  const getMaxThumb = methods.getThumbRenderFn({
16898
+ injectFormInput: false,
16735
16899
  focusValue: "max",
16736
16900
  getNodeData: () => ({
16737
16901
  ...maxEvents.value,
@@ -16830,8 +16994,8 @@
16830
16994
  }
16831
16995
  }
16832
16996
  model.value = model.value.min === null || model.value.max === null ? {
16833
- min: pos.min || props.min,
16834
- max: pos.max || props.max
16997
+ min: pos.min ?? props.min,
16998
+ max: pos.max ?? props.max
16835
16999
  } : {
16836
17000
  min: pos.min,
16837
17001
  max: pos.max
@@ -16926,7 +17090,7 @@
16926
17090
  selIconLen,
16927
17091
  selIcon: selIconLen > 0 ? props.iconSelected[selIconLen - 1] : props.iconSelected,
16928
17092
  halfIconLen,
16929
- halfIcon: halfIconLen > 0 ? props.iconHalf[selIconLen - 1] : props.iconHalf,
17093
+ halfIcon: halfIconLen > 0 ? props.iconHalf[halfIconLen - 1] : props.iconHalf,
16930
17094
  colorLen,
16931
17095
  color: colorLen > 0 ? props.color[colorLen - 1] : props.color,
16932
17096
  selColorLen,
@@ -16947,14 +17111,14 @@
16947
17111
  return (i, label) => `${label} ${i}`;
16948
17112
  });
16949
17113
  const stars = (0, vue.computed)(() => {
16950
- const acc = [], icons = iconData.value, ceil = Math.ceil(props.modelValue), tabindex = editable.value ? 0 : null;
17114
+ const acc = [], icons = iconData.value, ceil = Math.ceil(props.modelValue), tabIndex = Number.isInteger(props.modelValue) && props.modelValue >= 1 && props.modelValue <= props.max ? props.modelValue : 1;
16951
17115
  const halfIndex = props.iconHalf === void 0 || ceil === props.modelValue ? -1 : ceil;
16952
17116
  for (let i = 1; i <= props.max; i++) {
16953
17117
  const active = mouseModel.value === 0 && props.modelValue >= i || mouseModel.value > 0 && mouseModel.value >= i, half = halfIndex === i && mouseModel.value < i, exSelected = mouseModel.value > 0 && (half ? ceil : props.modelValue) >= i && mouseModel.value < i, color = half ? i <= icons.halfColorLen ? props.colorHalf[i - 1] : icons.halfColor : icons.selColor !== void 0 && active ? i <= icons.selColorLen ? props.colorSelected[i - 1] : icons.selColor : i <= icons.colorLen ? props.color[i - 1] : icons.color, name = (half ? i <= icons.halfIconLen ? props.iconHalf[i - 1] : icons.halfIcon : icons.selIcon !== void 0 && (active || exSelected) ? i <= icons.selIconLen ? props.iconSelected[i - 1] : icons.selIcon : i <= icons.iconLen ? props.icon[i - 1] : icons.icon) || $q.iconSet.rating.icon;
16954
17118
  acc.push({
16955
17119
  name: (half ? i <= icons.halfIconLen ? props.iconHalf[i - 1] : icons.halfIcon : icons.selIcon !== void 0 && (active || exSelected) ? i <= icons.selIconLen ? props.iconSelected[i - 1] : icons.selIcon : i <= icons.iconLen ? props.icon[i - 1] : icons.icon) || $q.iconSet.rating.icon,
16956
17120
  attrs: {
16957
- tabindex,
17121
+ tabindex: editable.value ? i === tabIndex ? 0 : -1 : null,
16958
17122
  role: "radio",
16959
17123
  "aria-checked": props.modelValue === i ? "true" : "false",
16960
17124
  "aria-label": iconLabel.value(i, name)
@@ -16980,17 +17144,25 @@
16980
17144
  function setHoverValue(value) {
16981
17145
  if (editable.value) mouseModel.value = value;
16982
17146
  }
16983
- function onKeyup(e, i) {
17147
+ function onKeydown(e, i) {
16984
17148
  switch (e.keyCode) {
16985
17149
  case 13:
16986
17150
  case 32:
16987
17151
  set(i);
16988
17152
  return stopAndPrevent(e);
16989
- case 37:
17153
+ case 37: {
17154
+ const index = i + ($q.lang.rtl ? 1 : -1);
17155
+ if (iconRefs[`rt${index}`]) iconRefs[`rt${index}`].focus();
17156
+ return stopAndPrevent(e);
17157
+ }
17158
+ case 39: {
17159
+ const index = i + ($q.lang.rtl ? -1 : 1);
17160
+ if (iconRefs[`rt${index}`]) iconRefs[`rt${index}`].focus();
17161
+ return stopAndPrevent(e);
17162
+ }
16990
17163
  case 40:
16991
17164
  if (iconRefs[`rt${i - 1}`]) iconRefs[`rt${i - 1}`].focus();
16992
17165
  return stopAndPrevent(e);
16993
- case 39:
16994
17166
  case 38:
16995
17167
  if (iconRefs[`rt${i + 1}`]) iconRefs[`rt${i + 1}`].focus();
16996
17168
  return stopAndPrevent(e);
@@ -17024,8 +17196,8 @@
17024
17196
  setHoverValue(i);
17025
17197
  },
17026
17198
  onBlur: resetMouseModel,
17027
- onKeyup(e) {
17028
- onKeyup(e, i);
17199
+ onKeydown(e) {
17200
+ onKeydown(e, i);
17029
17201
  }
17030
17202
  }, hMergeSlot(slots[`tip-${i}`], [(0, vue.h)(QIcon_default, {
17031
17203
  class: iconClass,
@@ -17140,11 +17312,11 @@
17140
17312
  ],
17141
17313
  verticalOffset: {
17142
17314
  type: Array,
17143
- default: [0, 0]
17315
+ default: () => [0, 0]
17144
17316
  },
17145
17317
  horizontalOffset: {
17146
17318
  type: Array,
17147
- default: [0, 0]
17319
+ default: () => [0, 0]
17148
17320
  },
17149
17321
  contentStyle: [
17150
17322
  Array,
@@ -17217,11 +17389,11 @@
17217
17389
  scroll.horizontal.percentage = (0, vue.computed)(() => {
17218
17390
  const diff = scroll.horizontal.size.value - container.horizontal.value;
17219
17391
  if (diff <= 0) return 0;
17220
- const p = between(Math.abs(scroll.horizontal.position.value) / diff, 0, 1);
17392
+ const p = between(getHorizontalLogicalPosition(scroll.horizontal.position.value) / diff, 0, 1);
17221
17393
  return Math.round(p * 1e4) / 1e4;
17222
17394
  });
17223
17395
  scroll.horizontal.thumbHidden = (0, vue.computed)(() => !(props.visible === null ? hover.value : props.visible) && !tempShowing.value && !panning.value || scroll.horizontal.size.value <= container.horizontal.value + 1);
17224
- scroll.horizontal.thumbStart = (0, vue.computed)(() => props.horizontalOffset[0] + scroll.horizontal.percentage.value * (container.horizontalInner.value - scroll.horizontal.thumbSize.value));
17396
+ scroll.horizontal.thumbStart = (0, vue.computed)(() => props.horizontalOffset[proxy.$q.lang.rtl ? 1 : 0] + scroll.horizontal.percentage.value * (container.horizontalInner.value - scroll.horizontal.thumbSize.value));
17225
17397
  scroll.horizontal.thumbSize = (0, vue.computed)(() => Math.round(between(container.horizontalInner.value * container.horizontalInner.value / scroll.horizontal.size.value, getMinThumbSize(container.horizontalInner.value), container.horizontalInner.value)));
17226
17398
  scroll.horizontal.style = (0, vue.computed)(() => ({
17227
17399
  ...props.thumbStyle,
@@ -17297,22 +17469,28 @@
17297
17469
  const data = scroll[axis];
17298
17470
  if (e.isFirst) {
17299
17471
  if (data.thumbHidden.value) return;
17300
- panRefPos = data.position.value;
17472
+ panRefPos = axis === "horizontal" ? getHorizontalLogicalPosition(data.position.value) : data.position.value;
17301
17473
  panning.value = true;
17302
17474
  } else if (!panning.value) return;
17303
17475
  if (e.isFinal) panning.value = false;
17304
17476
  const dProp = dirProps[axis];
17305
17477
  const multiplier = (data.size.value - container[axis].value) / (container[axis + "Inner"].value - data.thumbSize.value);
17306
17478
  const distance = e.distance[dProp.dist];
17307
- setScroll(panRefPos + (e.direction === dProp.dir ? 1 : -1) * distance * multiplier, axis);
17479
+ const direction = (e.direction === dProp.dir ? 1 : -1) * (axis === "horizontal" && proxy.$q.lang.rtl ? -1 : 1);
17480
+ const pos = panRefPos + direction * distance * multiplier;
17481
+ setScroll(axis === "horizontal" ? getHorizontalNativePosition(pos) : pos, axis);
17308
17482
  }
17309
17483
  function onMousedown(evt, axis) {
17310
17484
  const data = scroll[axis];
17311
17485
  if (!data.thumbHidden.value) {
17312
- const startOffset = axis === "vertical" ? props.verticalOffset[0] : props.horizontalOffset[0];
17313
- const offset = evt[dirProps[axis].offset] - startOffset;
17486
+ const isHorizontalRtl = axis === "horizontal" && proxy.$q.lang.rtl;
17487
+ const startOffset = axis === "vertical" ? props.verticalOffset[0] : props.horizontalOffset[isHorizontalRtl ? 1 : 0];
17488
+ const offset = (isHorizontalRtl ? container.horizontal.value - evt.offsetX : evt[dirProps[axis].offset]) - startOffset;
17314
17489
  const thumbStart = data.thumbStart.value - startOffset;
17315
- if (offset < thumbStart || offset > thumbStart + data.thumbSize.value) setScroll(between((offset - data.thumbSize.value / 2) / (container[axis + "Inner"].value - data.thumbSize.value), 0, 1) * Math.max(0, data.size.value - container[axis].value), axis);
17490
+ if (offset < thumbStart || offset > thumbStart + data.thumbSize.value) {
17491
+ const percentage = between((offset - data.thumbSize.value / 2) / (container[axis + "Inner"].value - data.thumbSize.value), 0, 1);
17492
+ setScroll(isHorizontalRtl ? getHorizontalNativePosition(percentage * Math.max(0, data.size.value - container[axis].value)) : percentage * Math.max(0, data.size.value - container[axis].value), axis);
17493
+ }
17316
17494
  if (data.ref.value !== null) data.ref.value.dispatchEvent(new MouseEvent(evt.type, evt));
17317
17495
  }
17318
17496
  }
@@ -17328,6 +17506,14 @@
17328
17506
  function setScroll(offset, axis) {
17329
17507
  targetRef.value[dirProps[axis].scroll] = offset;
17330
17508
  }
17509
+ function getHorizontalLogicalPosition(position, rtl = proxy.$q.lang.rtl) {
17510
+ if (!rtl) return position;
17511
+ return rtlHasScrollBug ? Math.max(0, scroll.horizontal.size.value - container.horizontal.value) - position : -position;
17512
+ }
17513
+ function getHorizontalNativePosition(position, rtl = proxy.$q.lang.rtl) {
17514
+ if (!rtl) return position;
17515
+ return rtlHasScrollBug ? Math.max(0, scroll.horizontal.size.value - container.horizontal.value) - position : -position;
17516
+ }
17331
17517
  let mouseEventTimer = null;
17332
17518
  function onMouseenter() {
17333
17519
  if (mouseEventTimer !== null) clearTimeout(mouseEventTimer);
@@ -17344,8 +17530,8 @@
17344
17530
  hover.value = false;
17345
17531
  }
17346
17532
  let scrollPosition = null;
17347
- (0, vue.watch)(() => proxy.$q.lang.rtl, (rtl) => {
17348
- if (targetRef.value !== null) setHorizontalScrollPosition(targetRef.value, Math.abs(scroll.horizontal.position.value) * (rtl ? -1 : 1));
17533
+ (0, vue.watch)(() => proxy.$q.lang.rtl, (rtl, oldRtl) => {
17534
+ if (targetRef.value !== null) setHorizontalScrollPosition(targetRef.value, getHorizontalNativePosition(getHorizontalLogicalPosition(scroll.horizontal.position.value, oldRtl), rtl));
17349
17535
  });
17350
17536
  (0, vue.onDeactivated)(() => {
17351
17537
  scrollPosition = {
@@ -17375,7 +17561,8 @@
17375
17561
  }),
17376
17562
  setScrollPosition: localSetScrollPosition,
17377
17563
  setScrollPercentage(axis, percentage, duration) {
17378
- localSetScrollPosition(axis, percentage * (scroll[axis].size.value - container[axis].value) * (axis === "horizontal" && proxy.$q.lang.rtl ? -1 : 1), duration);
17564
+ const offset = percentage * (scroll[axis].size.value - container[axis].value);
17565
+ localSetScrollPosition(axis, axis === "horizontal" ? getHorizontalNativePosition(offset) : offset, duration);
17379
17566
  }
17380
17567
  });
17381
17568
  const store = {
@@ -18966,11 +19153,12 @@
18966
19153
  if (pan.scale === 1) {
18967
19154
  node.style.transform = `translate${pan.axis}(${pan.dir * 100}%)`;
18968
19155
  if (timer !== null) clearTimeout(timer);
19156
+ const showing = pan.showing;
18969
19157
  timer = setTimeout(() => {
18970
19158
  timer = null;
18971
- emit(pan.showing, { reset });
19159
+ emit(showing, { reset });
18972
19160
  emit("action", {
18973
- side: pan.showing,
19161
+ side: showing,
18974
19162
  reset
18975
19163
  });
18976
19164
  }, 230);
@@ -19627,6 +19815,9 @@
19627
19815
  });
19628
19816
  //#endregion
19629
19817
  //#region src/components/stepper/StepHeader.js
19818
+ function preventSpace$1(e) {
19819
+ if (e.keyCode === 32) stopAndPrevent(e);
19820
+ }
19630
19821
  var StepHeader_default = createComponent({
19631
19822
  name: "StepHeader",
19632
19823
  props: {
@@ -19688,13 +19879,19 @@
19688
19879
  if (!isActive.value) props.goToPanel(props.step.name);
19689
19880
  }
19690
19881
  function onKeyup(e) {
19691
- if (e.keyCode === 13 && !isActive.value) props.goToPanel(props.step.name);
19882
+ if ([13, 32].includes(e.keyCode)) {
19883
+ if (!isActive.value) props.goToPanel(props.step.name);
19884
+ stopAndPrevent(e);
19885
+ }
19692
19886
  }
19693
19887
  return () => {
19694
19888
  const data = { class: classes.value };
19695
19889
  if (headerNav.value) {
19696
19890
  data.onClick = onActivate;
19891
+ data.onKeydown = preventSpace$1;
19697
19892
  data.onKeyup = onKeyup;
19893
+ data.role = "button";
19894
+ data["aria-current"] = isActive.value ? "step" : void 0;
19698
19895
  Object.assign(data, isDisable.value ? {
19699
19896
  tabindex: -1,
19700
19897
  "aria-disabled": "true"
@@ -19877,6 +20074,13 @@
19877
20074
  const onClick = (evt) => {
19878
20075
  emit("click", evt);
19879
20076
  };
20077
+ const onKeyup = (evt, col) => {
20078
+ if (evt.key === "Enter" || evt.key === " ") {
20079
+ props.props.sort(col);
20080
+ onClick(evt);
20081
+ evt.preventDefault();
20082
+ }
20083
+ };
19880
20084
  return () => {
19881
20085
  if (props.props === void 0) return (0, vue.h)("th", {
19882
20086
  class: props.autoWidth ? "q-table--col-auto-width" : "",
@@ -19884,7 +20088,7 @@
19884
20088
  }, hSlot(slots.default));
19885
20089
  let col, child;
19886
20090
  const name = vm.vnode.key;
19887
- if (name) {
20091
+ if (name !== null) {
19888
20092
  col = props.props.colsMap[name];
19889
20093
  if (col === void 0) return;
19890
20094
  } else col = props.props.col;
@@ -19896,14 +20100,25 @@
19896
20100
  name: $q.iconSet.table.arrowUp
19897
20101
  }));
19898
20102
  } else child = hSlot(slots.default);
19899
- return (0, vue.h)("th", {
20103
+ const data = {
19900
20104
  class: col.__thClass + (props.autoWidth ? " q-table--col-auto-width" : ""),
19901
20105
  style: col.headerStyle,
19902
20106
  onClick: (evt) => {
19903
20107
  if (col.sortable) props.props.sort(col);
19904
20108
  onClick(evt);
19905
20109
  }
19906
- }, child);
20110
+ };
20111
+ if (col.sortable) {
20112
+ data.tabindex = 0;
20113
+ data["aria-sort"] = col.__ariaSort;
20114
+ data.onKeydown = (evt) => {
20115
+ if (evt.key === " ") evt.preventDefault();
20116
+ };
20117
+ data.onKeyup = (evt) => {
20118
+ onKeyup(evt, col);
20119
+ };
20120
+ }
20121
+ return (0, vue.h)("th", data, child);
19907
20122
  };
19908
20123
  }
19909
20124
  });
@@ -20161,8 +20376,8 @@
20161
20376
  function requestServerInteraction(prop = {}) {
20162
20377
  (0, vue.nextTick)(() => {
20163
20378
  emit("request", {
20164
- pagination: prop.pagination || computedPagination.value,
20165
- filter: prop.filter || props.filter,
20379
+ pagination: prop.pagination === void 0 ? computedPagination.value : prop.pagination,
20380
+ filter: prop.filter === void 0 ? props.filter : prop.filter,
20166
20381
  getCellValue
20167
20382
  });
20168
20383
  });
@@ -20265,21 +20480,15 @@
20265
20480
  };
20266
20481
  const useTableRowSelectionEmits = ["update:selected", "selection"];
20267
20482
  function useTableRowSelection(props, emit, computedRows, getRowKey) {
20268
- const selectedKeys = (0, vue.computed)(() => {
20269
- const keys = {};
20270
- props.selected.map(getRowKey.value).forEach((key) => {
20271
- keys[key] = true;
20272
- });
20273
- return keys;
20274
- });
20483
+ const selectedKeys = (0, vue.computed)(() => new Set(props.selected.map(getRowKey.value)));
20275
20484
  const hasSelectionMode = (0, vue.computed)(() => props.selection !== "none");
20276
20485
  const singleSelection = (0, vue.computed)(() => props.selection === "single");
20277
20486
  const multipleSelection = (0, vue.computed)(() => props.selection === "multiple");
20278
- const allRowsSelected = (0, vue.computed)(() => computedRows.value.length !== 0 && computedRows.value.every((row) => selectedKeys.value[getRowKey.value(row)]));
20279
- const someRowsSelected = (0, vue.computed)(() => !allRowsSelected.value && computedRows.value.some((row) => selectedKeys.value[getRowKey.value(row)]));
20487
+ const allRowsSelected = (0, vue.computed)(() => computedRows.value.length !== 0 && computedRows.value.every((row) => selectedKeys.value.has(getRowKey.value(row))));
20488
+ const someRowsSelected = (0, vue.computed)(() => !allRowsSelected.value && computedRows.value.some((row) => selectedKeys.value.has(getRowKey.value(row))));
20280
20489
  const rowsSelectedNumber = (0, vue.computed)(() => props.selected.length);
20281
20490
  function isRowSelected(key) {
20282
- return selectedKeys.value[key] === true;
20491
+ return selectedKeys.value.has(key);
20283
20492
  }
20284
20493
  function clearSelection() {
20285
20494
  emit("update:selected", []);
@@ -20367,6 +20576,7 @@
20367
20576
  ...col,
20368
20577
  align,
20369
20578
  __iconClass: `q-table__sort-icon q-table__sort-icon--${align}`,
20579
+ __ariaSort: col.sortable === true ? col.name === sortBy ? descending ? "descending" : "ascending" : "none" : void 0,
20370
20580
  __thClass: alignClass + (col.headerClasses !== void 0 ? " " + col.headerClasses : "") + (col.sortable ? " sortable" : "") + (col.name === sortBy ? ` sorted ${descending ? "sort-desc" : ""}` : ""),
20371
20581
  __tdStyle: col.style !== void 0 ? typeof col.style !== "function" ? () => col.style : col.style : () => null,
20372
20582
  __tdClass: col.classes !== void 0 ? typeof col.classes !== "function" ? () => alignClass + " " + col.classes : (row) => alignClass + " " + col.classes(row) : () => alignClass
@@ -20377,7 +20587,7 @@
20377
20587
  colList,
20378
20588
  computedCols,
20379
20589
  computedColsMap: (0, vue.computed)(() => {
20380
- const names = {};
20590
+ const names = Object.create(null);
20381
20591
  computedCols.value.forEach((col) => {
20382
20592
  names[col.name] = col;
20383
20593
  });
@@ -20530,9 +20740,15 @@
20530
20740
  const cardDefaultClass = (0, vue.computed)(() => " q-table__card" + (isDark.value ? " q-table__card--dark q-dark" : "") + (props.square ? " q-table--square" : "") + (props.flat ? " q-table--flat" : "") + (props.bordered ? " q-table--bordered" : ""));
20531
20741
  const containerClass = (0, vue.computed)(() => `q-table__container q-table--${props.separator}-separator column no-wrap` + (props.grid ? " q-table--grid" : cardDefaultClass.value) + (isDark.value ? " q-table--dark" : "") + (props.dense ? " q-table--dense" : "") + (props.wrapCells ? "" : " q-table--no-wrap") + (inFullscreen.value ? " fullscreen scroll" : ""));
20532
20742
  const rootContainerClass = (0, vue.computed)(() => containerClass.value + (props.loading ? " q-table--loading" : ""));
20533
- (0, vue.watch)(() => props.tableStyle + props.tableClass + props.tableHeaderStyle + props.tableHeaderClass + containerClass.value, () => {
20743
+ (0, vue.watch)([
20744
+ () => props.tableStyle,
20745
+ () => props.tableClass,
20746
+ () => props.tableHeaderStyle,
20747
+ () => props.tableHeaderClass,
20748
+ containerClass
20749
+ ], () => {
20534
20750
  if (hasVirtScroll.value) virtScrollRef.value?.reset();
20535
- });
20751
+ }, { deep: true });
20536
20752
  const { innerPagination, computedPagination, isServerSide, requestServerInteraction, setPagination } = useTablePaginationState(vm, getCellValue);
20537
20753
  const { computedFilterMethod } = useTableFilter(props, setPagination);
20538
20754
  const { isRowExpanded, setExpanded, updateExpanded } = useTableRowExpand(props, emit);
@@ -20956,10 +21172,10 @@
20956
21172
  if (props.onRowClick !== void 0 || props.onRowDblclick !== void 0 || props.onRowContextmenu !== void 0) {
20957
21173
  data.class[0] += " cursor-pointer";
20958
21174
  if (props.onRowClick !== void 0) data.onClick = (evt) => {
20959
- emit("RowClick", evt, scope.row, scope.pageIndex);
21175
+ emit("rowClick", evt, scope.row, scope.pageIndex);
20960
21176
  };
20961
21177
  if (props.onRowDblclick !== void 0) data.onDblclick = (evt) => {
20962
- emit("RowDblclick", evt, scope.row, scope.pageIndex);
21178
+ emit("rowDblclick", evt, scope.row, scope.pageIndex);
20963
21179
  };
20964
21180
  if (props.onRowContextmenu !== void 0) data.onContextmenu = (evt) => {
20965
21181
  emit("rowContextmenu", evt, scope.row, scope.pageIndex);
@@ -21096,6 +21312,9 @@
21096
21312
  millisecond: d.getMilliseconds()
21097
21313
  };
21098
21314
  }
21315
+ function preventSpace(e) {
21316
+ if (e.keyCode === 32) stopAndPrevent(e);
21317
+ }
21099
21318
  function getWheelDist(a, b, threshold) {
21100
21319
  const diff = Math.abs(a - b);
21101
21320
  return Math.min(diff, threshold - diff);
@@ -21336,10 +21555,16 @@
21336
21555
  }
21337
21556
  };
21338
21557
  function setAmOnKey(e) {
21339
- if (e.keyCode === 13) setAm();
21558
+ if ([13, 32].includes(e.keyCode)) {
21559
+ setAm();
21560
+ stopAndPrevent(e);
21561
+ }
21340
21562
  }
21341
21563
  function setPmOnKey(e) {
21342
- if (e.keyCode === 13) setPm();
21564
+ if ([13, 32].includes(e.keyCode)) {
21565
+ setPm();
21566
+ stopAndPrevent(e);
21567
+ }
21343
21568
  }
21344
21569
  function onClick(evt) {
21345
21570
  if (!shouldAbortInteraction()) {
@@ -21351,8 +21576,10 @@
21351
21576
  if (!shouldAbortInteraction()) updateClock(evt, getClockRect());
21352
21577
  }
21353
21578
  function onKeyupHour(e) {
21354
- if (e.keyCode === 13) view.value = "hour";
21355
- else if ([37, 39].includes(e.keyCode)) {
21579
+ if ([13, 32].includes(e.keyCode)) {
21580
+ view.value = "hour";
21581
+ stopAndPrevent(e);
21582
+ } else if ([37, 39].includes(e.keyCode)) {
21356
21583
  const payload = e.keyCode === 37 ? -1 : 1;
21357
21584
  if (validHours.value !== null) {
21358
21585
  const values = computedFormat24h.value ? validHours.value.values : validHours.value[isAM.value ? "am" : "pm"].values;
@@ -21366,8 +21593,10 @@
21366
21593
  }
21367
21594
  }
21368
21595
  function onKeyupMinute(e) {
21369
- if (e.keyCode === 13) view.value = "minute";
21370
- else if ([37, 39].includes(e.keyCode)) {
21596
+ if ([13, 32].includes(e.keyCode)) {
21597
+ view.value = "minute";
21598
+ stopAndPrevent(e);
21599
+ } else if ([37, 39].includes(e.keyCode)) {
21371
21600
  const payload = e.keyCode === 37 ? -1 : 1;
21372
21601
  if (validMinutes.value !== null) {
21373
21602
  const values = validMinutes.value.values;
@@ -21378,13 +21607,15 @@
21378
21607
  }
21379
21608
  }
21380
21609
  function onKeyupSecond(e) {
21381
- if (e.keyCode === 13) view.value = "second";
21382
- else if ([37, 39].includes(e.keyCode)) {
21610
+ if ([13, 32].includes(e.keyCode)) {
21611
+ view.value = "second";
21612
+ stopAndPrevent(e);
21613
+ } else if ([37, 39].includes(e.keyCode)) {
21383
21614
  const payload = e.keyCode === 37 ? -1 : 1;
21384
21615
  if (validSeconds.value !== null) {
21385
21616
  const values = validSeconds.value.values;
21386
21617
  if (values.length === 0) return;
21387
- if (innerModel.value.seconds === null) setSecond(values[0]);
21618
+ if (innerModel.value.second === null) setSecond(values[0]);
21388
21619
  else setSecond(values[(values.length + values.indexOf(innerModel.value.second) + payload) % values.length]);
21389
21620
  } else setSecond((60 + (innerModel.value.second === null ? -payload : innerModel.value.second) + payload) % 60);
21390
21621
  }
@@ -21468,13 +21699,19 @@
21468
21699
  (0, vue.h)("div", {
21469
21700
  class: "q-time__link " + (view.value === "hour" ? "q-time__link--active" : "cursor-pointer"),
21470
21701
  tabindex: tabindex.value,
21702
+ role: "button",
21703
+ "aria-pressed": view.value === "hour" ? "true" : "false",
21471
21704
  onClick: setView.hour,
21705
+ onKeydown: preventSpace,
21472
21706
  onKeyup: onKeyupHour
21473
21707
  }, stringModel.value.hour),
21474
21708
  (0, vue.h)("div", ":"),
21475
21709
  (0, vue.h)("div", minLink.value ? {
21476
21710
  class: "q-time__link " + (view.value === "minute" ? "q-time__link--active" : "cursor-pointer"),
21477
21711
  tabindex: tabindex.value,
21712
+ role: "button",
21713
+ "aria-pressed": view.value === "minute" ? "true" : "false",
21714
+ onKeydown: preventSpace,
21478
21715
  onKeyup: onKeyupMinute,
21479
21716
  onClick: setView.minute
21480
21717
  } : { class: "q-time__link" }, stringModel.value.minute)
@@ -21482,6 +21719,9 @@
21482
21719
  if (props.withSeconds) label.push((0, vue.h)("div", ":"), (0, vue.h)("div", secLink.value ? {
21483
21720
  class: "q-time__link " + (view.value === "second" ? "q-time__link--active" : "cursor-pointer"),
21484
21721
  tabindex: tabindex.value,
21722
+ role: "button",
21723
+ "aria-pressed": view.value === "second" ? "true" : "false",
21724
+ onKeydown: preventSpace,
21485
21725
  onKeyup: onKeyupSecond,
21486
21726
  onClick: setView.second
21487
21727
  } : { class: "q-time__link" }, stringModel.value.second));
@@ -21492,12 +21732,18 @@
21492
21732
  if (!computedFormat24h.value) child.push((0, vue.h)("div", { class: "q-time__header-ampm column items-between no-wrap" }, [(0, vue.h)("div", {
21493
21733
  class: "q-time__link " + (isAM.value ? "q-time__link--active" : "cursor-pointer"),
21494
21734
  tabindex: tabindex.value,
21735
+ role: "button",
21736
+ "aria-pressed": isAM.value ? "true" : "false",
21495
21737
  onClick: setAm,
21738
+ onKeydown: preventSpace,
21496
21739
  onKeyup: setAmOnKey
21497
21740
  }, "AM"), (0, vue.h)("div", {
21498
21741
  class: "q-time__link " + (isAM.value ? "cursor-pointer" : "q-time__link--active"),
21499
21742
  tabindex: tabindex.value,
21743
+ role: "button",
21744
+ "aria-pressed": isAM.value ? "false" : "true",
21500
21745
  onClick: setPm,
21746
+ onKeydown: preventSpace,
21501
21747
  onKeyup: setPmOnKey
21502
21748
  }, "PM")]));
21503
21749
  return (0, vue.h)("div", { class: "q-time__header flex flex-center no-wrap " + headerClass.value }, child);
@@ -21739,9 +21985,11 @@
21739
21985
  const lazy = (0, vue.ref)({});
21740
21986
  const innerTicked = (0, vue.ref)(props.ticked || []);
21741
21987
  const innerExpanded = (0, vue.ref)(props.expanded || []);
21742
- let blurTargets = {};
21988
+ const focusedKey = (0, vue.ref)(null);
21989
+ let blurTargets = {}, headerTargets = {};
21743
21990
  (0, vue.onBeforeUpdate)(() => {
21744
21991
  blurTargets = {};
21992
+ headerTargets = {};
21745
21993
  });
21746
21994
  const classes = (0, vue.computed)(() => `q-tree q-tree--${props.dense ? "dense" : "standard"}` + (props.noConnectors ? " q-tree--no-connectors" : "") + (isDark.value ? " q-tree--dark" : "") + (props.color !== void 0 ? ` text-${props.color}` : ""));
21747
21995
  const hasSelection = (0, vue.computed)(() => props.selected !== void 0);
@@ -21814,6 +22062,25 @@
21814
22062
  props.nodes.forEach((node) => travel(node, null));
21815
22063
  return acc;
21816
22064
  });
22065
+ const focusableKeys = (0, vue.computed)(() => {
22066
+ const acc = [];
22067
+ function travel(nodes) {
22068
+ nodes.forEach((node) => {
22069
+ const localMeta = meta.value[node[props.nodeKey]];
22070
+ if (props.filter && localMeta.matchesFilter !== true) return;
22071
+ if (localMeta.link === true) acc.push(localMeta.key);
22072
+ if (localMeta.expanded === true && Array.isArray(node[props.childrenKey])) travel(node[props.childrenKey]);
22073
+ });
22074
+ }
22075
+ travel(props.nodes);
22076
+ return acc;
22077
+ });
22078
+ const tabKey = (0, vue.computed)(() => {
22079
+ const keys = focusableKeys.value;
22080
+ if (keys.includes(focusedKey.value)) return focusedKey.value;
22081
+ const selected = keys.find((key) => meta.value[key].selected === true);
22082
+ return selected !== void 0 ? selected : keys[0];
22083
+ });
21817
22084
  (0, vue.watch)(() => props.ticked, (val) => {
21818
22085
  innerTicked.value = val;
21819
22086
  });
@@ -21944,16 +22211,25 @@
21944
22211
  class: `q-tree__node relative-position q-tree__node--${isParent ? "parent" : "child"}`
21945
22212
  }, [(0, vue.h)("div", {
21946
22213
  class: "q-tree__node-header relative-position row no-wrap items-center" + (m.link === true ? " q-tree__node--link q-hoverable q-focusable" : "") + (m.selected === true ? " q-tree__node--selected" : "") + (m.disabled === true ? " q-tree__node--disabled" : ""),
21947
- tabindex: m.link === true ? 0 : -1,
21948
- ariaExpanded: children.length !== 0 ? m.expanded : null,
22214
+ ref: (el) => {
22215
+ headerTargets[m.key] = el;
22216
+ },
22217
+ tabindex: m.link === true && m.key === tabKey.value ? 0 : -1,
22218
+ "aria-expanded": isParent ? m.expanded ? "true" : "false" : null,
22219
+ "aria-selected": m.selectable ? m.selected ? "true" : "false" : null,
22220
+ "aria-disabled": m.disabled === true ? "true" : null,
21949
22221
  role: "treeitem",
22222
+ onFocus() {
22223
+ if (m.link === true) focusedKey.value = m.key;
22224
+ },
21950
22225
  onClick: (e) => {
21951
22226
  onClick(node, m, e);
21952
22227
  },
21953
- onKeypress(e) {
22228
+ onKeydown(e) {
21954
22229
  if (shouldIgnoreKey(e) !== true) {
21955
22230
  if (e.keyCode === 13) onClick(node, m, e, true);
21956
22231
  else if (e.keyCode === 32) onExpandClick(node, m, e, true);
22232
+ else if (onNavigationKey(m, e.keyCode)) stopAndPrevent(e);
21957
22233
  }
21958
22234
  }
21959
22235
  }, [
@@ -22009,7 +22285,59 @@
22009
22285
  function blur(key) {
22010
22286
  blurTargets[key]?.focus();
22011
22287
  }
22288
+ function focusNode(key) {
22289
+ if (key !== void 0) {
22290
+ focusedKey.value = key;
22291
+ headerTargets[key]?.focus();
22292
+ }
22293
+ }
22294
+ function getFirstFocusableChild(children) {
22295
+ for (const child of children) {
22296
+ if (props.filter && child.matchesFilter !== true) continue;
22297
+ if (child.link === true) return child.key;
22298
+ if (child.expanded === true) {
22299
+ const key = getFirstFocusableChild(child.children);
22300
+ if (key !== void 0) return key;
22301
+ }
22302
+ }
22303
+ }
22304
+ function onNavigationKey(localMeta, keyCode) {
22305
+ const keys = focusableKeys.value, index = keys.indexOf(localMeta.key);
22306
+ if (keyCode === 36) {
22307
+ focusNode(keys[0]);
22308
+ return true;
22309
+ }
22310
+ if (keyCode === 35) {
22311
+ focusNode(keys.at(-1));
22312
+ return true;
22313
+ }
22314
+ if (keyCode === 38) {
22315
+ focusNode(keys[index - 1]);
22316
+ return true;
22317
+ }
22318
+ if (keyCode === 40) {
22319
+ focusNode(keys[index + 1]);
22320
+ return true;
22321
+ }
22322
+ if (keyCode === 39) {
22323
+ if (localMeta.isParent !== true && !localMeta.lazy) return true;
22324
+ if (localMeta.expanded !== true) setExpanded(localMeta.key, true);
22325
+ else focusNode(getFirstFocusableChild(localMeta.children));
22326
+ return true;
22327
+ }
22328
+ if (keyCode === 37) {
22329
+ if (localMeta.expanded === true) setExpanded(localMeta.key, false);
22330
+ else {
22331
+ let parent = localMeta.parent;
22332
+ while (parent !== null && parent.link !== true) parent = parent.parent;
22333
+ focusNode(parent?.key);
22334
+ }
22335
+ return true;
22336
+ }
22337
+ return false;
22338
+ }
22012
22339
  function onClick(node, localMeta, e, keyboard) {
22340
+ if (localMeta.link === true) focusedKey.value = localMeta.key;
22013
22341
  if (keyboard !== true && localMeta.selectable !== false) blur(localMeta.key);
22014
22342
  if (hasSelection.value && localMeta.selectable) {
22015
22343
  if (!props.noSelectionUnset) emit("update:selected", localMeta.key !== props.selected ? localMeta.key : null);
@@ -22018,6 +22346,7 @@
22018
22346
  if (typeof node.handler === "function") node.handler(node);
22019
22347
  }
22020
22348
  function onExpandClick(node, localMeta, e, keyboard) {
22349
+ if (localMeta.link === true) focusedKey.value = localMeta.key;
22021
22350
  if (e !== void 0) stopAndPrevent(e);
22022
22351
  if (keyboard !== true && localMeta.selectable !== false) blur(localMeta.key);
22023
22352
  setExpanded(localMeta.key, !localMeta.expanded, node, localMeta);
@@ -22108,7 +22437,7 @@
22108
22437
  return;
22109
22438
  }
22110
22439
  file.__uploaded = status === "uploaded" ? file.size : uploadedSize;
22111
- file.__progress = status === "uploaded" ? 1 : Math.min(.9999, file.__uploaded / file.size);
22440
+ file.__progress = status === "uploaded" ? 1 : file.size === 0 ? 0 : Math.min(.9999, file.__uploaded / file.size);
22112
22441
  file.__progressLabel = getProgressLabel(file.__progress);
22113
22442
  proxy.$forceUpdate();
22114
22443
  }
@@ -22165,7 +22494,9 @@
22165
22494
  }
22166
22495
  }
22167
22496
  function removeUploadedFiles() {
22168
- if (!props.disable) batchRemoveFiles(["uploaded"], () => {
22497
+ if (!props.disable) batchRemoveFiles(["uploaded"], ({ size }) => {
22498
+ state.uploadedSize.value -= size;
22499
+ uploadSize.value -= size;
22169
22500
  state.uploadedFiles.value = [];
22170
22501
  });
22171
22502
  }
@@ -22196,8 +22527,12 @@
22196
22527
  }
22197
22528
  function removeFile(file) {
22198
22529
  if (props.disable) return;
22199
- if (file.__status === "uploaded") state.uploadedFiles.value = state.uploadedFiles.value.filter((f) => f.__key !== file.__key);
22200
- else if (file.__status === "uploading") file.__abort();
22530
+ const isUploading = file.__status === "uploading";
22531
+ if (file.__status === "uploaded") {
22532
+ state.uploadedSize.value -= file.size;
22533
+ uploadSize.value -= file.size;
22534
+ state.uploadedFiles.value = state.uploadedFiles.value.filter((f) => f.__key !== file.__key);
22535
+ } else if (isUploading) uploadSize.value -= file.size;
22201
22536
  else uploadSize.value -= file.size;
22202
22537
  state.files.value = state.files.value.filter((f) => {
22203
22538
  if (f.__key !== file.__key) return true;
@@ -22205,6 +22540,7 @@
22205
22540
  return false;
22206
22541
  });
22207
22542
  state.queuedFiles.value = state.queuedFiles.value.filter((f) => f.__key !== file.__key);
22543
+ if (isUploading) file.__abort();
22208
22544
  emit("removed", [file]);
22209
22545
  }
22210
22546
  function revokeImgURLs() {
@@ -22429,6 +22765,7 @@
22429
22765
  const xhrs = (0, vue.ref)([]);
22430
22766
  const promises = (0, vue.ref)([]);
22431
22767
  const workingThreads = (0, vue.ref)(0);
22768
+ const abortedPromises = /* @__PURE__ */ new WeakSet();
22432
22769
  const xhrProps = (0, vue.computed)(() => ({
22433
22770
  url: getFn(props.url),
22434
22771
  method: getFn(props.method),
@@ -22441,12 +22778,14 @@
22441
22778
  }));
22442
22779
  const isUploading = (0, vue.computed)(() => workingThreads.value > 0);
22443
22780
  const isBusy = (0, vue.computed)(() => promises.value.length !== 0);
22444
- let abortPromises;
22781
+ const getLiveFiles = (files) => files.filter((file) => helpers.files.value.includes(file));
22445
22782
  function abort() {
22446
22783
  xhrs.value.forEach((x) => {
22447
22784
  x.abort();
22448
22785
  });
22449
- if (promises.value.length !== 0) abortPromises = true;
22786
+ promises.value.forEach((promise) => {
22787
+ abortedPromises.add(promise);
22788
+ });
22450
22789
  }
22451
22790
  function upload() {
22452
22791
  const queue = [...helpers.queuedFiles.value];
@@ -22458,36 +22797,57 @@
22458
22797
  }
22459
22798
  function runFactory(files) {
22460
22799
  workingThreads.value++;
22800
+ const failed = (err, promise) => {
22801
+ if (helpers.isAlive()) {
22802
+ if (promise !== void 0) promises.value = promises.value.filter((p) => p !== promise);
22803
+ const liveFiles = getLiveFiles(files);
22804
+ if (liveFiles.length !== 0) {
22805
+ helpers.queuedFiles.value.push(...liveFiles);
22806
+ liveFiles.forEach((f) => {
22807
+ helpers.updateFileStatus(f, "failed");
22808
+ });
22809
+ emit("factoryFailed", err, liveFiles);
22810
+ }
22811
+ workingThreads.value--;
22812
+ }
22813
+ };
22461
22814
  if (typeof props.factory !== "function") {
22462
- performUpload(files, {});
22815
+ startUpload({});
22463
22816
  return;
22464
22817
  }
22465
- const res = props.factory(files);
22466
- if (!res) {
22467
- emit("factoryFailed", /* @__PURE__ */ new Error("QUploader: factory() does not return properly"), files);
22468
- workingThreads.value--;
22469
- } else if (typeof res.catch === "function" && typeof res.then === "function") {
22818
+ let res;
22819
+ try {
22820
+ res = props.factory(files);
22821
+ } catch (err) {
22822
+ failed(err);
22823
+ return;
22824
+ }
22825
+ if (Object(res) !== res) failed(/* @__PURE__ */ new Error("QUploader: factory() does not return properly"));
22826
+ else if (typeof res.catch === "function" && typeof res.then === "function") {
22470
22827
  promises.value.push(res);
22471
- const failed = (err) => {
22472
- if (helpers.isAlive()) {
22473
- promises.value = promises.value.filter((p) => p !== res);
22474
- if (promises.value.length === 0) abortPromises = false;
22475
- helpers.queuedFiles.value.push(...files);
22476
- files.forEach((f) => {
22477
- helpers.updateFileStatus(f, "failed");
22478
- });
22479
- emit("factoryFailed", err, files);
22480
- workingThreads.value--;
22481
- }
22482
- };
22483
22828
  res.then((factory) => {
22484
- if (abortPromises) failed(/* @__PURE__ */ new Error("Aborted"));
22829
+ if (abortedPromises.has(res)) failed(/* @__PURE__ */ new Error("Aborted"), res);
22830
+ else if (Object(factory) !== factory) failed(/* @__PURE__ */ new Error("QUploader: factory() does not return properly"), res);
22485
22831
  else if (helpers.isAlive()) {
22486
22832
  promises.value = promises.value.filter((p) => p !== res);
22487
- performUpload(files, factory);
22833
+ startUpload(factory);
22488
22834
  }
22489
- }).catch(failed);
22490
- } else performUpload(files, res || {});
22835
+ }).catch((err) => {
22836
+ failed(err, res);
22837
+ });
22838
+ } else startUpload(res);
22839
+ function startUpload(factory) {
22840
+ const liveFiles = getLiveFiles(files);
22841
+ if (liveFiles.length === 0) {
22842
+ workingThreads.value--;
22843
+ return;
22844
+ }
22845
+ try {
22846
+ performUpload(liveFiles, factory);
22847
+ } catch (err) {
22848
+ failed(err);
22849
+ }
22850
+ }
22491
22851
  }
22492
22852
  function performUpload(files, factory) {
22493
22853
  const form = new FormData(), xhr = new XMLHttpRequest();
@@ -22495,6 +22855,10 @@
22495
22855
  const url = getProp("url", files);
22496
22856
  if (!url) {
22497
22857
  console.error("q-uploader: invalid or no URL specified");
22858
+ helpers.queuedFiles.value.push(...files);
22859
+ files.forEach((f) => {
22860
+ helpers.updateFileStatus(f, "failed");
22861
+ });
22498
22862
  workingThreads.value--;
22499
22863
  return;
22500
22864
  }
@@ -22511,7 +22875,7 @@
22511
22875
  let size = localUploadedSize - uploadIndexSize;
22512
22876
  for (let i = uploadIndex; size > 0 && i < files.length; i++) {
22513
22877
  const file = files[i];
22514
- if (size > file.size) {
22878
+ if (size >= file.size) {
22515
22879
  size -= file.size;
22516
22880
  uploadIndex++;
22517
22881
  uploadIndexSize += file.size;
@@ -22525,25 +22889,33 @@
22525
22889
  xhr.addEventListener("readystatechange", () => {
22526
22890
  if (xhr.readyState < 4) return;
22527
22891
  if (xhr.status && xhr.status < 400) {
22528
- helpers.uploadedFiles.value.push(...files);
22529
- files.forEach((f) => {
22530
- helpers.updateFileStatus(f, "uploaded");
22531
- });
22532
- emit("uploaded", {
22533
- files,
22534
- xhr
22535
- });
22892
+ const liveFiles = getLiveFiles(files);
22893
+ const liveUploadSize = liveFiles.reduce((total, file) => total + file.size, 0);
22894
+ helpers.uploadedSize.value += liveUploadSize - localUploadedSize;
22895
+ if (liveFiles.length !== 0) {
22896
+ helpers.uploadedFiles.value.push(...liveFiles);
22897
+ liveFiles.forEach((f) => {
22898
+ helpers.updateFileStatus(f, "uploaded");
22899
+ });
22900
+ emit("uploaded", {
22901
+ files: liveFiles,
22902
+ xhr
22903
+ });
22904
+ }
22536
22905
  } else {
22537
22906
  aborted = true;
22538
22907
  helpers.uploadedSize.value -= localUploadedSize;
22539
- helpers.queuedFiles.value.push(...files);
22540
- files.forEach((f) => {
22541
- helpers.updateFileStatus(f, "failed");
22542
- });
22543
- emit("failed", {
22544
- files,
22545
- xhr
22546
- });
22908
+ const liveFiles = getLiveFiles(files);
22909
+ if (liveFiles.length !== 0) {
22910
+ helpers.queuedFiles.value.push(...liveFiles);
22911
+ liveFiles.forEach((f) => {
22912
+ helpers.updateFileStatus(f, "failed");
22913
+ });
22914
+ emit("failed", {
22915
+ files: liveFiles,
22916
+ xhr
22917
+ });
22918
+ }
22547
22919
  }
22548
22920
  workingThreads.value--;
22549
22921
  xhrs.value = xhrs.value.filter((x) => x !== xhr);
@@ -23945,7 +24317,7 @@
23945
24317
  if (keyRegex.test(key)) {
23946
24318
  const parsedKey = Number.parseInt(key, 10);
23947
24319
  const keyCode = Number.isNaN(parsedKey) ? keyCodes[key.toLowerCase()] : parsedKey;
23948
- if (keyCode >= 0) acc.push(keyCode);
24320
+ if (keyCode !== void 0) acc.push(...[keyCode].flat());
23949
24321
  }
23950
24322
  return acc;
23951
24323
  }, []);
@@ -24526,7 +24898,11 @@
24526
24898
  function read(string) {
24527
24899
  if (string === "") return string;
24528
24900
  if (string.indexOf("\"") === 0) string = string.slice(1, -1).replaceAll(String.raw`\"`, "\"").replaceAll(String.raw`\\`, "\\");
24529
- string = decodeURIComponent(string.replaceAll("+", " "));
24901
+ try {
24902
+ string = decodeURIComponent(string.replaceAll("+", " "));
24903
+ } catch {
24904
+ return;
24905
+ }
24530
24906
  try {
24531
24907
  const parsed = JSON.parse(string);
24532
24908
  if (parsed === Object(parsed) || Array.isArray(parsed)) string = parsed;
@@ -24550,15 +24926,19 @@
24550
24926
  const unit = match[2];
24551
24927
  totalSeconds += value * numberUnitMultiplierMap[unit];
24552
24928
  }
24553
- return hasMatch ? totalSeconds : void 0;
24929
+ if (hasMatch) return totalSeconds;
24930
+ const timestamp = Date.parse(str);
24931
+ return Number.isNaN(timestamp) ? void 0 : Math.round((timestamp - Date.now()) / 1e3);
24554
24932
  }
24555
24933
  function set(key, val, opts = {}, ssr) {
24556
24934
  let maxAge;
24557
24935
  let isDeletion = false;
24558
24936
  if (opts.expires !== void 0) {
24559
24937
  if (Number.isFinite(opts.expires)) maxAge = Math.round(opts.expires * 86400);
24560
- else if (opts.expires instanceof Date) maxAge = Math.round((opts.expires.getTime() - Date.now()) / 1e3);
24561
- else if (typeof opts.expires === "string") maxAge = parseExpireToSeconds(opts.expires);
24938
+ else if (opts.expires instanceof Date) {
24939
+ const timestamp = opts.expires.getTime();
24940
+ if (Number.isFinite(timestamp)) maxAge = Math.round((timestamp - Date.now()) / 1e3);
24941
+ } else if (typeof opts.expires === "string") maxAge = parseExpireToSeconds(opts.expires);
24562
24942
  if (maxAge !== void 0) isDeletion = maxAge <= 0;
24563
24943
  }
24564
24944
  const keyValue = `${encodeURIComponent(key)}=${stringifyCookieValue(val)}`;
@@ -24578,8 +24958,8 @@
24578
24958
  ssr.res.setHeader("Set-Cookie", ssr.req.qCookies);
24579
24959
  let all = ssr.req.headers.cookie || "";
24580
24960
  if (maxAge !== void 0 && isDeletion) {
24581
- const localVal = get(key, ssr);
24582
- if (localVal !== void 0) all = all.replace(`${key}=${localVal}; `, "").replace(`; ${key}=${localVal}`, "").replace(`${key}=${localVal}`, "");
24961
+ const encodedKey = encodeURIComponent(key);
24962
+ all = all.split("; ").filter((entry) => entry.split("=", 1)[0] !== encodedKey).join("; ");
24583
24963
  } else all = all ? `${keyValue}; ${all}` : keyValue;
24584
24964
  ssr.req.headers.cookie = all;
24585
24965
  } else document.cookie = cookie;
@@ -24589,11 +24969,15 @@
24589
24969
  let result = key ? null : {}, i = 0, parts, name, cookie;
24590
24970
  for (; i < l; i++) {
24591
24971
  parts = cookies[i].split("=");
24592
- name = decodeURIComponent(parts.shift());
24972
+ try {
24973
+ name = decodeURIComponent(parts.shift());
24974
+ } catch {
24975
+ continue;
24976
+ }
24593
24977
  cookie = parts.join("=");
24594
24978
  if (!key) result[name] = cookie;
24595
24979
  else if (key === name) {
24596
- result = read(cookie);
24980
+ result = read(cookie) ?? null;
24597
24981
  break;
24598
24982
  }
24599
24983
  }
@@ -24989,6 +25373,7 @@
24989
25373
  //#region src/plugins/meta/Meta.js
24990
25374
  let updateId = null;
24991
25375
  let currentClientMeta;
25376
+ String.raw`\u003C`, String.raw`\u003E`, String.raw`\u0026`, String.raw`\u2028`, String.raw`\u2029`;
24992
25377
  const clientList = [];
24993
25378
  function normalize(meta) {
24994
25379
  if (meta.title) {
@@ -26002,7 +26387,7 @@
26002
26387
  */
26003
26388
  if (window.Vue === void 0) console.error("[ Quasar ] Vue is required to run. Please add a script tag for it before loading Quasar.");
26004
26389
  window.Quasar = {
26005
- version: "2.21.3",
26390
+ version: "2.22.0",
26006
26391
  install(app, opts) {
26007
26392
  install_quasar_default(app, {
26008
26393
  components: components_exports,