quasar 2.3.1 → 2.4.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 (315) hide show
  1. package/dist/api/AppFullscreen.json +15 -8
  2. package/dist/api/BottomSheet.json +6 -0
  3. package/dist/api/Cookies.json +4 -3
  4. package/dist/api/Dialog.json +24 -10
  5. package/dist/api/Loading.json +0 -2
  6. package/dist/api/LoadingBar.json +8 -3
  7. package/dist/api/Morph.json +14 -7
  8. package/dist/api/Mutation.json +1 -1
  9. package/dist/api/Notify.json +41 -27
  10. package/dist/api/QAjaxBar.json +6 -3
  11. package/dist/api/QBreadcrumbs.json +8 -4
  12. package/dist/api/QBreadcrumbsEl.json +35 -12
  13. package/dist/api/QBtn.json +36 -17
  14. package/dist/api/QBtnDropdown.json +41 -20
  15. package/dist/api/QBtnToggle.json +7 -2
  16. package/dist/api/QCard.json +2 -1
  17. package/dist/api/QCardActions.json +2 -1
  18. package/dist/api/QCardSection.json +2 -1
  19. package/dist/api/QCarousel.json +10 -5
  20. package/dist/api/QCarouselControl.json +4 -2
  21. package/dist/api/QChatMessage.json +0 -4
  22. package/dist/api/QCheckbox.json +8 -4
  23. package/dist/api/QChip.json +2 -1
  24. package/dist/api/QCircularProgress.json +14 -7
  25. package/dist/api/QColor.json +6 -3
  26. package/dist/api/QDate.json +33 -5
  27. package/dist/api/QDialog.json +8 -4
  28. package/dist/api/QDrawer.json +10 -5
  29. package/dist/api/QEditor.json +10 -5
  30. package/dist/api/QExpansionItem.json +36 -13
  31. package/dist/api/QFab.json +41 -6
  32. package/dist/api/QFabAction.json +12 -2
  33. package/dist/api/QField.json +3 -1
  34. package/dist/api/QFile.json +8 -2
  35. package/dist/api/QFooter.json +2 -1
  36. package/dist/api/QForm.json +1 -1
  37. package/dist/api/QHeader.json +4 -2
  38. package/dist/api/QIcon.json +2 -1
  39. package/dist/api/QImg.json +8 -4
  40. package/dist/api/QInfiniteScroll.json +6 -3
  41. package/dist/api/QInnerLoading.json +8 -4
  42. package/dist/api/QInput.json +3 -1
  43. package/dist/api/QIntersection.json +4 -2
  44. package/dist/api/QItem.json +33 -11
  45. package/dist/api/QKnob.json +8 -4
  46. package/dist/api/QLayout.json +9 -1
  47. package/dist/api/QLinearProgress.json +4 -2
  48. package/dist/api/QMarkupTable.json +2 -1
  49. package/dist/api/QMenu.json +8 -4
  50. package/dist/api/QNoSsr.json +2 -1
  51. package/dist/api/QOptionGroup.json +76 -5
  52. package/dist/api/QPage.json +2 -1
  53. package/dist/api/QPageScroller.json +8 -4
  54. package/dist/api/QPageSticky.json +2 -1
  55. package/dist/api/QPagination.json +10 -6
  56. package/dist/api/QParallax.json +2 -1
  57. package/dist/api/QPopupEdit.json +5 -2
  58. package/dist/api/QPopupProxy.json +7 -4
  59. package/dist/api/QRange.json +600 -111
  60. package/dist/api/QRating.json +5 -2
  61. package/dist/api/QResizeObserver.json +4 -1
  62. package/dist/api/QRouteTab.json +35 -13
  63. package/dist/api/QScrollArea.json +29 -6
  64. package/dist/api/QScrollObserver.json +13 -1
  65. package/dist/api/QSelect.json +76 -47
  66. package/dist/api/QSeparator.json +2 -1
  67. package/dist/api/QSkeleton.json +8 -4
  68. package/dist/api/QSlideItem.json +9 -0
  69. package/dist/api/QSlideTransition.json +2 -1
  70. package/dist/api/QSlider.json +512 -43
  71. package/dist/api/QSpinner.json +2 -1
  72. package/dist/api/QSplitter.json +4 -2
  73. package/dist/api/QStep.json +2 -1
  74. package/dist/api/QStepper.json +6 -3
  75. package/dist/api/QTab.json +4 -2
  76. package/dist/api/QTabPanels.json +6 -3
  77. package/dist/api/QTable.json +154 -88
  78. package/dist/api/QTabs.json +4 -2
  79. package/dist/api/QTime.json +16 -4
  80. package/dist/api/QTimeline.json +4 -2
  81. package/dist/api/QTimelineEntry.json +4 -2
  82. package/dist/api/QToggle.json +8 -4
  83. package/dist/api/QTooltip.json +18 -9
  84. package/dist/api/QTree.json +34 -19
  85. package/dist/api/QUploader.json +28 -6
  86. package/dist/api/QVirtualScroll.json +26 -11
  87. package/dist/api/ScrollFire.json +1 -1
  88. package/dist/api/TouchHold.json +2 -1
  89. package/dist/api/TouchRepeat.json +2 -1
  90. package/dist/api/TouchSwipe.json +2 -1
  91. package/dist/icon-set/bootstrap-icons.umd.prod.js +1 -1
  92. package/dist/icon-set/eva-icons.umd.prod.js +1 -1
  93. package/dist/icon-set/fontawesome-v5-pro.umd.prod.js +1 -1
  94. package/dist/icon-set/fontawesome-v5.umd.prod.js +1 -1
  95. package/dist/icon-set/ionicons-v4.umd.prod.js +1 -1
  96. package/dist/icon-set/line-awesome.umd.prod.js +1 -1
  97. package/dist/icon-set/material-icons-outlined.umd.prod.js +1 -1
  98. package/dist/icon-set/material-icons-round.umd.prod.js +1 -1
  99. package/dist/icon-set/material-icons-sharp.umd.prod.js +1 -1
  100. package/dist/icon-set/material-icons.umd.prod.js +1 -1
  101. package/dist/icon-set/mdi-v3.umd.prod.js +1 -1
  102. package/dist/icon-set/mdi-v4.umd.prod.js +1 -1
  103. package/dist/icon-set/mdi-v5.umd.prod.js +1 -1
  104. package/dist/icon-set/mdi-v6.umd.prod.js +1 -1
  105. package/dist/icon-set/svg-bootstrap-icons.umd.prod.js +1 -1
  106. package/dist/icon-set/svg-eva-icons.umd.prod.js +1 -1
  107. package/dist/icon-set/svg-fontawesome-v5.umd.prod.js +1 -1
  108. package/dist/icon-set/svg-ionicons-v4.umd.prod.js +1 -1
  109. package/dist/icon-set/svg-ionicons-v5.umd.prod.js +1 -1
  110. package/dist/icon-set/svg-ionicons-v6.umd.prod.js +6 -0
  111. package/dist/icon-set/svg-line-awesome.umd.prod.js +1 -1
  112. package/dist/icon-set/svg-material-icons-outlined.umd.prod.js +1 -1
  113. package/dist/icon-set/svg-material-icons-round.umd.prod.js +1 -1
  114. package/dist/icon-set/svg-material-icons-sharp.umd.prod.js +1 -1
  115. package/dist/icon-set/svg-material-icons.umd.prod.js +1 -1
  116. package/dist/icon-set/svg-mdi-v4.umd.prod.js +1 -1
  117. package/dist/icon-set/svg-mdi-v5.umd.prod.js +1 -1
  118. package/dist/icon-set/svg-mdi-v6.umd.prod.js +1 -1
  119. package/dist/icon-set/svg-themify.umd.prod.js +1 -1
  120. package/dist/icon-set/themify.umd.prod.js +1 -1
  121. package/dist/lang/ar.umd.prod.js +1 -1
  122. package/dist/lang/az-Latn.umd.prod.js +1 -1
  123. package/dist/lang/bg.umd.prod.js +1 -1
  124. package/dist/lang/bn.umd.prod.js +1 -1
  125. package/dist/lang/ca.umd.prod.js +1 -1
  126. package/dist/lang/cs.umd.prod.js +1 -1
  127. package/dist/lang/da.umd.prod.js +1 -1
  128. package/dist/lang/de.umd.prod.js +1 -1
  129. package/dist/lang/el.umd.prod.js +1 -1
  130. package/dist/lang/en-GB.umd.prod.js +1 -1
  131. package/dist/lang/en-US.umd.prod.js +1 -1
  132. package/dist/lang/eo.umd.prod.js +1 -1
  133. package/dist/lang/es.umd.prod.js +1 -1
  134. package/dist/lang/et.umd.prod.js +1 -1
  135. package/dist/lang/fa-IR.umd.prod.js +1 -1
  136. package/dist/lang/fa.umd.prod.js +1 -1
  137. package/dist/lang/fi.umd.prod.js +1 -1
  138. package/dist/lang/fr.umd.prod.js +1 -1
  139. package/dist/lang/gn.umd.prod.js +1 -1
  140. package/dist/lang/he.umd.prod.js +1 -1
  141. package/dist/lang/hr.umd.prod.js +1 -1
  142. package/dist/lang/hu.umd.prod.js +1 -1
  143. package/dist/lang/id.umd.prod.js +1 -1
  144. package/dist/lang/is.umd.prod.js +1 -1
  145. package/dist/lang/it.umd.prod.js +1 -1
  146. package/dist/lang/ja.umd.prod.js +1 -1
  147. package/dist/lang/km.umd.prod.js +1 -1
  148. package/dist/lang/ko-KR.umd.prod.js +1 -1
  149. package/dist/lang/kur-CKB.umd.prod.js +1 -1
  150. package/dist/lang/lt.umd.prod.js +1 -1
  151. package/dist/lang/lu.umd.prod.js +1 -1
  152. package/dist/lang/lv.umd.prod.js +1 -1
  153. package/dist/lang/ml.umd.prod.js +1 -1
  154. package/dist/lang/ms.umd.prod.js +1 -1
  155. package/dist/lang/nb-NO.umd.prod.js +1 -1
  156. package/dist/lang/nl.umd.prod.js +1 -1
  157. package/dist/lang/pl.umd.prod.js +1 -1
  158. package/dist/lang/pt-BR.umd.prod.js +1 -1
  159. package/dist/lang/pt.umd.prod.js +1 -1
  160. package/dist/lang/ro.umd.prod.js +1 -1
  161. package/dist/lang/ru.umd.prod.js +1 -1
  162. package/dist/lang/sk.umd.prod.js +1 -1
  163. package/dist/lang/sl.umd.prod.js +1 -1
  164. package/dist/lang/sr-CYR.umd.prod.js +1 -1
  165. package/dist/lang/sr.umd.prod.js +1 -1
  166. package/dist/lang/sv.umd.prod.js +1 -1
  167. package/dist/lang/ta.umd.prod.js +1 -1
  168. package/dist/lang/th.umd.prod.js +1 -1
  169. package/dist/lang/tr.umd.prod.js +1 -1
  170. package/dist/lang/ug.umd.prod.js +1 -1
  171. package/dist/lang/uk.umd.prod.js +1 -1
  172. package/dist/lang/vi.umd.prod.js +1 -1
  173. package/dist/lang/zh-CN.umd.prod.js +1 -1
  174. package/dist/lang/zh-TW.umd.prod.js +1 -1
  175. package/dist/quasar.cjs.prod.js +2 -2
  176. package/dist/quasar.css +268 -184
  177. package/dist/quasar.esm.prod.js +2 -2
  178. package/dist/quasar.prod.css +1 -1
  179. package/dist/quasar.rtl.css +340 -263
  180. package/dist/quasar.rtl.prod.css +1 -1
  181. package/dist/quasar.sass +272 -212
  182. package/dist/quasar.umd.js +16532 -16216
  183. package/dist/quasar.umd.prod.js +2 -2
  184. package/dist/ssr-directives/Morph.js +1 -1
  185. package/dist/transforms/loader-asset-urls.json +20 -0
  186. package/dist/types/api/cookies.d.ts +1 -1
  187. package/dist/types/api/slider.d.ts +46 -0
  188. package/dist/types/api/validation.d.ts +4 -0
  189. package/dist/types/api.d.ts +2 -0
  190. package/dist/types/composables.d.ts +7 -3
  191. package/dist/types/extras/icon-set.d.ts +1 -0
  192. package/dist/types/index.d.ts +759 -177
  193. package/dist/vetur/quasar-attributes.json +251 -83
  194. package/dist/vetur/quasar-tags.json +59 -17
  195. package/dist/web-types/web-types.json +587 -155
  196. package/icon-set/svg-ionicons-v6.js +225 -0
  197. package/package.json +2 -2
  198. package/src/api.extends.json +0 -1
  199. package/src/components/breadcrumbs/QBreadcrumbs.js +7 -2
  200. package/src/components/breadcrumbs/QBreadcrumbs.sass +0 -3
  201. package/src/components/breadcrumbs/QBreadcrumbsEl.js +14 -8
  202. package/src/components/btn/QBtn.js +6 -5
  203. package/src/components/btn/use-btn.js +21 -21
  204. package/src/components/btn/use-btn.json +22 -13
  205. package/src/components/btn-dropdown/QBtnDropdown.json +1 -0
  206. package/src/components/btn-toggle/QBtnToggle.json +3 -0
  207. package/src/components/checkbox/use-checkbox.js +1 -1
  208. package/src/components/chip/QChip.json +1 -2
  209. package/src/components/color/QColor.js +32 -26
  210. package/src/components/color/QColor.sass +10 -23
  211. package/src/components/date/QDate.json +25 -1
  212. package/src/components/date/QDate.sass +2 -0
  213. package/src/components/drawer/QDrawer.js +18 -15
  214. package/src/components/editor/QEditor.js +3 -3
  215. package/src/components/editor/QEditor.sass +10 -1
  216. package/src/components/expansion-item/QExpansionItem.js +4 -1
  217. package/src/components/expansion-item/QExpansionItem.json +2 -1
  218. package/src/components/fab/QFab.js +18 -12
  219. package/src/components/fab/QFab.json +36 -1
  220. package/src/components/fab/QFab.sass +1 -1
  221. package/src/components/fab/QFabAction.js +14 -7
  222. package/src/components/fab/QFabAction.json +10 -0
  223. package/src/components/field/QField.json +3 -3
  224. package/src/components/file/QFile.js +12 -5
  225. package/src/components/file/QFile.json +9 -6
  226. package/src/components/file/QFile.sass +4 -2
  227. package/src/components/footer/QFooter.js +1 -1
  228. package/src/components/form/QForm.json +2 -3
  229. package/src/components/header/QHeader.js +1 -1
  230. package/src/components/icon/QIcon.js +2 -2
  231. package/src/components/infinite-scroll/QInfiniteScroll.js +4 -5
  232. package/src/components/item/QItem.js +2 -3
  233. package/src/components/layout/QLayout.json +8 -1
  234. package/src/components/linear-progress/QLinearProgress.js +3 -2
  235. package/src/components/linear-progress/QLinearProgress.sass +1 -1
  236. package/src/components/option-group/QOptionGroup.js +3 -0
  237. package/src/components/option-group/QOptionGroup.json +48 -2
  238. package/src/components/pagination/QPagination.json +0 -1
  239. package/src/components/parallax/QParallax.js +4 -2
  240. package/src/components/popup-edit/QPopupEdit.js +2 -5
  241. package/src/components/popup-edit/QPopupEdit.json +1 -0
  242. package/src/components/popup-proxy/QPopupProxy.json +2 -1
  243. package/src/components/radio/QRadio.js +2 -7
  244. package/src/components/range/QRange.js +103 -222
  245. package/src/components/range/QRange.json +11 -121
  246. package/src/components/rating/QRating.json +1 -1
  247. package/src/components/resize-observer/QResizeObserver.json +2 -0
  248. package/src/components/scroll-area/QScrollArea.js +11 -14
  249. package/src/components/scroll-area/QScrollArea.json +29 -9
  250. package/src/components/scroll-observer/QScrollObserver.json +11 -0
  251. package/src/components/select/QSelect.js +1 -1
  252. package/src/components/select/QSelect.json +41 -15
  253. package/src/components/slide-item/QSlideItem.json +9 -0
  254. package/src/components/slider/QSlider.js +46 -132
  255. package/src/components/slider/QSlider.json +1 -121
  256. package/src/components/slider/QSlider.sass +198 -132
  257. package/src/components/slider/use-slider.js +453 -109
  258. package/src/components/slider/use-slider.json +546 -0
  259. package/src/components/stepper/QStepper.js +3 -3
  260. package/src/components/stepper/QStepper.sass +24 -26
  261. package/src/components/table/QTable.js +27 -47
  262. package/src/components/table/QTable.json +104 -55
  263. package/src/components/table/table-pagination.js +4 -0
  264. package/src/components/tabs/QRouteTab.js +1 -2
  265. package/src/components/tabs/QRouteTab.json +0 -7
  266. package/src/components/tabs/QTabs.js +71 -20
  267. package/src/components/tabs/use-tab.js +26 -13
  268. package/src/components/time/QTime.json +8 -0
  269. package/src/components/tree/QTree.js +14 -12
  270. package/src/components/tree/QTree.json +26 -21
  271. package/src/components/tree/QTree.sass +45 -41
  272. package/src/components/uploader/QUploader.json +14 -2
  273. package/src/components/uploader/uploader-core.js +16 -9
  274. package/src/components/uploader/xhr-uploader-plugin.json +8 -3
  275. package/src/components/virtual-scroll/QVirtualScroll.json +15 -0
  276. package/src/components/virtual-scroll/QVirtualScroll.sass +1 -0
  277. package/src/components/virtual-scroll/use-virtual-scroll.js +30 -17
  278. package/src/components/virtual-scroll/use-virtual-scroll.json +7 -5
  279. package/src/composables/private/use-field.js +7 -7
  280. package/src/composables/private/use-file.js +20 -5
  281. package/src/composables/private/use-form.js +2 -3
  282. package/src/composables/private/use-fullscreen.js +15 -4
  283. package/src/composables/private/use-router-link.js +44 -23
  284. package/src/composables/private/use-router-link.json +26 -10
  285. package/src/composables/private/use-split-attrs.js +12 -9
  286. package/src/composables/private/use-validate.js +21 -15
  287. package/src/composables/private/use-validate.json +1 -0
  288. package/src/composables/use-dialog-plugin-component.js +1 -0
  289. package/src/css/core/helpers.sass +3 -0
  290. package/src/css/core/positioning.sass +5 -0
  291. package/src/directives/Mutation.json +2 -3
  292. package/src/directives/ScrollFire.js +1 -0
  293. package/src/directives/ScrollFire.json +2 -3
  294. package/src/icon-set.js +2 -4
  295. package/src/plugins/AppFullscreen.js +70 -53
  296. package/src/plugins/AppFullscreen.json +8 -8
  297. package/src/plugins/AppVisibility.js +2 -3
  298. package/src/plugins/BottomSheet.js +3 -5
  299. package/src/plugins/Cookies.json +2 -2
  300. package/src/plugins/Dialog.js +3 -5
  301. package/src/plugins/Dialog.json +6 -5
  302. package/src/plugins/LoadingBar.js +17 -18
  303. package/src/plugins/LoadingBar.json +4 -3
  304. package/src/plugins/Notify.js +296 -295
  305. package/src/plugins/Notify.json +13 -19
  306. package/src/plugins/Platform.js +14 -14
  307. package/src/utils/date.js +4 -4
  308. package/src/utils/dom.js +2 -2
  309. package/src/utils/open-url.js +2 -2
  310. package/src/utils/patterns.js +1 -0
  311. package/src/utils/private/define-reactive-plugin.js +10 -8
  312. package/src/utils/private/global-dialog.js +6 -8
  313. package/src/utils/private/global-dialog.json +6 -0
  314. package/src/utils/private/inject-obj-prop.js +13 -0
  315. package/src/utils/private/is.js +2 -2
@@ -210,7 +210,7 @@ export function getRenderer (getPlugin) {
210
210
  removed.size += f.size
211
211
  removed.files.push(f)
212
212
 
213
- f._img !== void 0 && window.URL.revokeObjectURL(f._img.src)
213
+ f.__img !== void 0 && window.URL.revokeObjectURL(f.__img.src)
214
214
 
215
215
  return false
216
216
  })
@@ -226,7 +226,7 @@ export function getRenderer (getPlugin) {
226
226
  if (props.disable) { return }
227
227
 
228
228
  if (file.__status === 'uploaded') {
229
- state.uploadedFiles.value = state.uploadedFiles.value.filter(f => f.name !== file.name)
229
+ state.uploadedFiles.value = state.uploadedFiles.value.filter(f => f.__key !== file.__key)
230
230
  }
231
231
  else if (file.__status === 'uploading') {
232
232
  file.__abort()
@@ -236,21 +236,22 @@ export function getRenderer (getPlugin) {
236
236
  }
237
237
 
238
238
  state.files.value = state.files.value.filter(f => {
239
- if (f.name !== file.name) {
239
+ if (f.__key !== file.__key) {
240
240
  return true
241
241
  }
242
242
 
243
- f._img !== void 0 && window.URL.revokeObjectURL(f._img.src)
243
+ f.__img !== void 0 && window.URL.revokeObjectURL(f.__img.src)
244
244
 
245
245
  return false
246
246
  })
247
- state.queuedFiles.value = state.queuedFiles.value.filter(f => f.name !== file.name)
247
+
248
+ state.queuedFiles.value = state.queuedFiles.value.filter(f => f.__key !== file.__key)
248
249
  emit('removed', [ file ])
249
250
  }
250
251
 
251
252
  function revokeImgURLs () {
252
253
  state.files.value.forEach(f => {
253
- f._img !== void 0 && window.URL.revokeObjectURL(f._img.src)
254
+ f.__img !== void 0 && window.URL.revokeObjectURL(f.__img.src)
254
255
  })
255
256
  }
256
257
 
@@ -303,6 +304,7 @@ export function getRenderer (getPlugin) {
303
304
  let child = void 0
304
305
 
305
306
  if (icon === 'add') {
307
+ data.onClick = pickFiles
306
308
  child = renderInput
307
309
  }
308
310
  else {
@@ -324,6 +326,7 @@ export function getRenderer (getPlugin) {
324
326
  multiple: props.multiple === true ? 'multiple' : void 0,
325
327
  capture: props.capture,
326
328
  onMousedown: stop, // need to stop refocus from QBtn
329
+ onClick: pickFiles,
327
330
  onChange: addFilesToQueue
328
331
  })
329
332
  }
@@ -367,7 +370,7 @@ export function getRenderer (getPlugin) {
367
370
  }
368
371
 
369
372
  return state.files.value.map(file => h('div', {
370
- key: file.name,
373
+ key: file.__key,
371
374
  class: 'q-uploader__file relative-position'
372
375
  + (props.noThumbnails !== true && file.__img !== void 0 ? ' q-uploader__file--img' : '')
373
376
  + (
@@ -441,11 +444,15 @@ export function getRenderer (getPlugin) {
441
444
  uploadProgressLabel: uploadProgressLabel.value
442
445
  }
443
446
 
444
- Object.keys(state).forEach(key => {
447
+ for (const key in state) {
445
448
  acc[ key ] = isRef(state[ key ]) === true
446
449
  ? state[ key ].value
447
450
  : state[ key ]
448
- })
451
+ }
452
+
453
+ // TODO: (Qv3) Put the QUploader instance under `ref`
454
+ // property for consistency and flexibility
455
+ // return { ref: { ...acc, ...publicMethods } }
449
456
  return { ...acc, ...publicMethods }
450
457
  })
451
458
 
@@ -223,11 +223,13 @@
223
223
  "definition": {
224
224
  "files": {
225
225
  "type": "Array",
226
+ "required": true,
226
227
  "desc": "Uploaded files",
227
228
  "__exemption": [ "examples" ]
228
229
  },
229
230
  "xhr": {
230
231
  "type": "Object",
232
+ "required": true,
231
233
  "desc": "XMLHttpRequest that has been used to upload this batch of files",
232
234
  "__exemption": [ "examples" ]
233
235
  }
@@ -245,11 +247,13 @@
245
247
  "definition": {
246
248
  "files": {
247
249
  "type": "Array",
250
+ "required": true,
248
251
  "desc": "Files which encountered error",
249
252
  "__exemption": [ "examples" ]
250
253
  },
251
254
  "xhr": {
252
255
  "type": "Object",
256
+ "required": true,
253
257
  "desc": "XMLHttpRequest that has been used to upload this batch of files",
254
258
  "__exemption": [ "examples" ]
255
259
  }
@@ -267,11 +271,13 @@
267
271
  "definition": {
268
272
  "files": {
269
273
  "type": "Array",
274
+ "required": true,
270
275
  "desc": "Files which are now uploading",
271
276
  "__exemption": [ "examples" ]
272
277
  },
273
278
  "xhr": {
274
279
  "type": "Object",
280
+ "required": true,
275
281
  "desc": "XMLHttpRequest used for uploading",
276
282
  "__exemption": [ "examples" ]
277
283
  }
@@ -284,9 +290,8 @@
284
290
  "desc": "Emitted when factory function is supplied with a Promise which is rejected",
285
291
  "params": {
286
292
  "err": {
287
- "type": "Object",
288
- "desc": "Error Object which is the Promise rejection reason",
289
- "__exemption": [ "examples" ]
293
+ "type": "Error",
294
+ "desc": "Error object which is the Promise rejection reason"
290
295
  },
291
296
  "files": {
292
297
  "type": "Array",
@@ -67,6 +67,21 @@
67
67
  }
68
68
  },
69
69
 
70
+ "events": {
71
+ "virtual-scroll": {
72
+ "params": {
73
+ "details": {
74
+ "definition": {
75
+ "ref": {
76
+ "tsType": "QVirtualScroll",
77
+ "desc": "Vue reference to the QVirtualScroll"
78
+ }
79
+ }
80
+ }
81
+ }
82
+ }
83
+ },
84
+
70
85
  "slots" : {
71
86
  "before": {
72
87
  "desc": "Template slot for the elements that should be rendered before the list; Suggestion: thead before a table"
@@ -4,6 +4,7 @@
4
4
 
5
5
  &__content
6
6
  outline: none
7
+ contain: content
7
8
 
8
9
  *
9
10
  overflow-anchor: none
@@ -15,8 +15,8 @@ const scrollToEdges = [
15
15
  'end-force'
16
16
  ]
17
17
 
18
- const slice = Array.prototype.slice
19
18
  let id = 1
19
+ const filterProto = Array.prototype.filter
20
20
 
21
21
  const setOverflowAnchor = __QUASAR_SSR__ || window.getComputedStyle(document.body).overflowAnchor === void 0
22
22
  ? noop
@@ -66,7 +66,7 @@ function getScrollDetails (
66
66
  if (horizontal === true) {
67
67
  if (parent === window) {
68
68
  details.scrollStart = window.pageXOffset || window.scrollX || document.body.scrollLeft || 0
69
- details.scrollViewSize += window.innerWidth
69
+ details.scrollViewSize += document.documentElement.clientWidth
70
70
  }
71
71
  else {
72
72
  details.scrollStart = parentCalc.scrollLeft
@@ -81,7 +81,7 @@ function getScrollDetails (
81
81
  else {
82
82
  if (parent === window) {
83
83
  details.scrollStart = window.pageYOffset || window.scrollY || document.body.scrollTop || 0
84
- details.scrollViewSize += window.innerHeight
84
+ details.scrollViewSize += document.documentElement.clientHeight
85
85
  }
86
86
  else {
87
87
  details.scrollStart = parentCalc.scrollTop
@@ -130,10 +130,16 @@ function getScrollDetails (
130
130
  }
131
131
 
132
132
  function setScroll (parent, scroll, horizontal, rtl) {
133
+ if (scroll === 'end') {
134
+ scroll = (parent === window ? document.body : parent)[
135
+ horizontal === true ? 'scrollWidth' : 'scrollHeight'
136
+ ]
137
+ }
138
+
133
139
  if (parent === window) {
134
140
  if (horizontal === true) {
135
141
  if (rtl === true) {
136
- scroll = (rtlHasScrollBug === true ? document.body.scrollWidth - window.innerWidth : 0) - scroll
142
+ scroll = (rtlHasScrollBug === true ? document.body.scrollWidth - document.documentElement.clientWidth : 0) - scroll
137
143
  }
138
144
  window.scrollTo(scroll, window.pageYOffset || window.scrollY || document.body.scrollTop || 0)
139
145
  }
@@ -398,20 +404,17 @@ export function useVirtualScroll ({
398
404
  }
399
405
 
400
406
  const { activeElement } = document
407
+ const contentEl = contentRef.value
401
408
  if (
402
409
  rangeChanged === true
403
- && contentRef.value !== null
404
- && contentRef.value !== activeElement
405
- && contentRef.value.contains(activeElement) === true
410
+ && contentEl !== null
411
+ && contentEl !== activeElement
412
+ && contentEl.contains(activeElement) === true
406
413
  ) {
407
- const onBlurFn = () => {
408
- contentRef.value.focus()
409
- }
414
+ contentEl.addEventListener('focusout', onBlurRefocusFn)
410
415
 
411
- activeElement.addEventListener('blur', onBlurFn, true)
412
-
413
- requestAnimationFrame(() => {
414
- activeElement.removeEventListener('blur', onBlurFn, true)
416
+ setTimeout(() => {
417
+ contentEl !== void 0 && contentEl.removeEventListener('focusout', onBlurRefocusFn)
415
418
  })
416
419
  }
417
420
 
@@ -489,8 +492,10 @@ export function useVirtualScroll ({
489
492
 
490
493
  if (contentEl) {
491
494
  const
492
- children = slice.call(contentEl.children)
493
- .filter(el => el.classList.contains('q-virtual-scroll--skip') === false),
495
+ children = filterProto.call(
496
+ contentEl.children,
497
+ el => el.classList && el.classList.contains('q-virtual-scroll--skip') === false
498
+ ),
494
499
  childrenLength = children.length,
495
500
  sizeFn = props.virtualScrollHorizontal === true
496
501
  ? el => el.getBoundingClientRect().width
@@ -521,6 +526,10 @@ export function useVirtualScroll ({
521
526
  }
522
527
  }
523
528
 
529
+ function onBlurRefocusFn () {
530
+ contentRef.value !== void 0 && contentRef.value.focus()
531
+ }
532
+
524
533
  function localResetVirtualScroll (toIndex, fullReset) {
525
534
  const defaultSize = 1 * virtualScrollItemSizeComputed.value
526
535
 
@@ -673,7 +682,10 @@ export function useVirtualScroll ({
673
682
  }
674
683
 
675
684
  setVirtualScrollSize()
676
- const onVirtualScrollEvt = debounce(localOnVirtualScrollEvt, $q.platform.is.ios === true ? 120 : 35)
685
+ const onVirtualScrollEvt = debounce(
686
+ localOnVirtualScrollEvt,
687
+ $q.platform.is.ios === true ? 120 : 35
688
+ )
677
689
 
678
690
  onBeforeMount(() => {
679
691
  setVirtualScrollSize()
@@ -698,6 +710,7 @@ export function useVirtualScroll ({
698
710
  setOverflowAnchor !== noop && onBeforeUnmount(() => {
699
711
  const styleSheet = document.getElementById(vsId + '_ss')
700
712
  styleSheet !== null && styleSheet.remove()
713
+ onVirtualScrollEvt.cancel()
701
714
  })
702
715
 
703
716
  // expose public methods
@@ -72,30 +72,32 @@
72
72
  "definition": {
73
73
  "index": {
74
74
  "type": "Number",
75
+ "required": true,
75
76
  "desc": "Index of the list item that was scrolled into view (0 based)",
76
77
  "examples": [ 30 ]
77
78
  },
78
79
  "from": {
79
80
  "type": "Number",
81
+ "required": true,
80
82
  "desc": "The index of the first list item that is rendered (0 based)",
81
83
  "examples": [ 10 ]
82
84
  },
83
85
  "to": {
84
86
  "type": "Number",
87
+ "required": true,
85
88
  "desc": "The index of the last list item that is rendered (0 based)",
86
89
  "examples": [ 50 ]
87
90
  },
88
91
  "direction": {
89
92
  "type": "String",
93
+ "required": true,
90
94
  "desc": "Direction of change",
91
95
  "values": [ "increase", "decrease" ]
92
96
  },
93
97
  "ref": {
94
- "type": "Object",
95
- "desc": "Vue reference to the QVirtualList which triggered the event",
96
- "__exemption": [
97
- "examples"
98
- ]
98
+ "type": "Component",
99
+ "required": true,
100
+ "desc": "Vue reference to the component which triggered the event"
99
101
  }
100
102
  }
101
103
  }
@@ -75,7 +75,7 @@ export const useFieldProps = {
75
75
  export const useFieldEmits = [ 'update:modelValue', 'clear', 'focus', 'blur', 'popup-show', 'popup-hide' ]
76
76
 
77
77
  export function useFieldState () {
78
- const { props, attrs, proxy } = getCurrentInstance()
78
+ const { props, attrs, proxy, vnode } = getCurrentInstance()
79
79
 
80
80
  const isDark = useDark(props, proxy.$q)
81
81
 
@@ -90,7 +90,7 @@ export function useFieldState () {
90
90
  focused: ref(false),
91
91
  hasPopupOpen: false,
92
92
 
93
- splitAttrs: useSplitAttrs(attrs),
93
+ splitAttrs: useSplitAttrs(attrs, vnode),
94
94
  targetUid: ref(getTargetUid(props.for)),
95
95
 
96
96
  rootRef: ref(null),
@@ -168,7 +168,7 @@ export default function (state) {
168
168
  isDirtyModel,
169
169
  hasRules,
170
170
  hasError,
171
- computedErrorMessage,
171
+ errorMessage,
172
172
  resetValidation
173
173
  } = useValidate(state.focused, state.innerLoading)
174
174
 
@@ -348,7 +348,7 @@ export default function (state) {
348
348
  nextTick(() => {
349
349
  resetValidation()
350
350
 
351
- if (props.lazyRules !== 'ondemand' && $q.platform.is.mobile !== true) {
351
+ if ($q.platform.is.mobile !== true) {
352
352
  isDirtyModel.value = false
353
353
  }
354
354
  })
@@ -473,9 +473,9 @@ export default function (state) {
473
473
  let msg, key
474
474
 
475
475
  if (hasError.value === true) {
476
- if (computedErrorMessage.value !== null) {
477
- msg = [ h('div', { role: 'alert' }, computedErrorMessage.value) ]
478
- key = `q--slot-error-${ computedErrorMessage.value }`
476
+ if (errorMessage.value !== null) {
477
+ msg = [ h('div', { role: 'alert' }, errorMessage.value) ]
478
+ key = `q--slot-error-${ errorMessage.value }`
479
479
  }
480
480
  else {
481
481
  msg = hSlot(slots.error)
@@ -1,6 +1,6 @@
1
1
  import { h, computed, getCurrentInstance } from 'vue'
2
2
 
3
- import { stopAndPrevent } from '../../utils/event.js'
3
+ import { stop, stopAndPrevent } from '../../utils/event.js'
4
4
 
5
5
  function filterFiles (files, rejectedFiles, failedPropValidation, filterFn) {
6
6
  const acceptedFiles = []
@@ -62,8 +62,18 @@ export default function ({
62
62
 
63
63
  function pickFiles (e) {
64
64
  if (editable.value) {
65
- const input = getFileInput()
66
- input && input.click(e)
65
+ if (e !== Object(e)) {
66
+ e = { target: null }
67
+ }
68
+
69
+ if (e.target !== null && e.target.matches('input[type="file"]') === true) {
70
+ // stop propagation if it's not a real pointer event
71
+ e.clientX === 0 && e.clientY === 0 && stop(e)
72
+ }
73
+ else {
74
+ const input = getFileInput()
75
+ input && input !== e.target && input.click(e)
76
+ }
67
77
  }
68
78
  }
69
79
 
@@ -112,10 +122,15 @@ export default function ({
112
122
  files = [ files[ 0 ] ]
113
123
  }
114
124
 
125
+ // Compute key to use for each file
126
+ files.forEach(file => {
127
+ file.__key = file.webkitRelativePath + file.lastModified + file.name + file.size
128
+ })
129
+
115
130
  // Avoid duplicate files
116
- const filenameMap = currentFileList.map(entry => entry.name)
131
+ const filenameMap = currentFileList.map(entry => entry.__key)
117
132
  files = filterFiles(files, rejectedFiles, 'duplicate', file => {
118
- return filenameMap.includes(file.name) === false
133
+ return filenameMap.includes(file.__key) === false
119
134
  })
120
135
 
121
136
  if (files.length === 0) { return done() }
@@ -12,13 +12,12 @@ export function useFormAttrs (props) {
12
12
  }))
13
13
  }
14
14
 
15
- export function useFormInject (formAttrs = {}, formDomProps = {}) {
15
+ export function useFormInject (formAttrs = {}) {
16
16
  return (child, action, className) => {
17
17
  child[ action ](
18
18
  h('input', {
19
19
  class: 'hidden' + (className || ''),
20
- ...formAttrs.value,
21
- ...formDomProps.value
20
+ ...formAttrs.value
22
21
  })
23
22
  )
24
23
  }
@@ -3,6 +3,8 @@ import { ref, watch, onBeforeMount, onMounted, onBeforeUnmount, getCurrentInstan
3
3
  import History from '../../history.js'
4
4
  import { vmHasRouter } from '../../utils/private/vm.js'
5
5
 
6
+ let counter = 0
7
+
6
8
  export const useFullscreenProps = {
7
9
  fullscreen: Boolean,
8
10
  noRouteFullscreenExit: Boolean
@@ -50,7 +52,11 @@ export default function () {
50
52
  container = proxy.$el.parentNode
51
53
  container.replaceChild(fullscreenFillerNode, proxy.$el)
52
54
  document.body.appendChild(proxy.$el)
53
- document.body.classList.add('q-body--fullscreen-mixin')
55
+
56
+ counter++
57
+ if (counter === 1) {
58
+ document.body.classList.add('q-body--fullscreen-mixin')
59
+ }
54
60
 
55
61
  historyEntry = {
56
62
  handler: exitFullscreen
@@ -69,11 +75,16 @@ export default function () {
69
75
  }
70
76
 
71
77
  container.replaceChild(proxy.$el, fullscreenFillerNode)
72
- document.body.classList.remove('q-body--fullscreen-mixin')
73
78
  inFullscreen.value = false
74
79
 
75
- if (proxy.$el.scrollIntoView !== void 0) {
76
- setTimeout(() => { proxy.$el.scrollIntoView() })
80
+ counter = Math.max(0, counter - 1)
81
+
82
+ if (counter === 0) {
83
+ document.body.classList.remove('q-body--fullscreen-mixin')
84
+
85
+ if (proxy.$el.scrollIntoView !== void 0) {
86
+ setTimeout(() => { proxy.$el.scrollIntoView() })
87
+ }
77
88
  }
78
89
  }
79
90
 
@@ -79,6 +79,7 @@ function isSameRouteLocationParams (a, b) {
79
79
  }
80
80
 
81
81
  export const useRouterLinkProps = {
82
+ // router-link
82
83
  to: [ String, Object ],
83
84
  replace: Boolean,
84
85
  exact: Boolean,
@@ -90,23 +91,33 @@ export const useRouterLinkProps = {
90
91
  type: String,
91
92
  default: 'q-router-link--exact-active'
92
93
  },
94
+
95
+ // regular <a> link
96
+ href: String,
97
+ target: String,
98
+
99
+ // state
93
100
  disable: Boolean
94
101
  }
95
102
 
96
- export default function () {
103
+ // external props: type, tag
104
+
105
+ export default function (fallbackTag) {
97
106
  const vm = getCurrentInstance()
98
- const { props, attrs, proxy } = vm
107
+ const { props, proxy } = vm
99
108
 
100
109
  const hasRouter = vmHasRouter(vm)
110
+ const hasHrefLink = computed(() => props.disable !== true && props.href !== void 0)
101
111
 
102
- const hasLinkConfigured = computed(() =>
112
+ const hasRouterLinkProps = computed(() =>
103
113
  hasRouter === true
104
114
  && props.disable !== true
115
+ && hasHrefLink.value !== true
105
116
  && props.to !== void 0 && props.to !== null && props.to !== ''
106
117
  )
107
118
 
108
119
  const linkRoute = computed(() => {
109
- if (hasLinkConfigured.value === true) {
120
+ if (hasRouterLinkProps.value === true) {
110
121
  try { return proxy.$router.resolve(props.to) }
111
122
  catch (err) {}
112
123
  }
@@ -114,16 +125,33 @@ export default function () {
114
125
  return null
115
126
  })
116
127
 
117
- const hasLink = computed(() => linkRoute.value !== null)
128
+ const hasRouterLink = computed(() => linkRoute.value !== null)
129
+ const hasLink = computed(() => hasHrefLink.value === true || hasRouterLink.value === true)
118
130
 
119
131
  const linkTag = computed(() => (
120
- hasLink.value === true
132
+ props.type === 'a' || hasLink.value === true
121
133
  ? 'a'
122
- : (props.tag || 'div')
134
+ : (props.tag || fallbackTag || 'div')
135
+ ))
136
+
137
+ const linkProps = computed(() => (
138
+ hasHrefLink.value === true
139
+ ? {
140
+ href: props.href,
141
+ target: props.target
142
+ }
143
+ : (
144
+ hasRouterLink.value === true
145
+ ? {
146
+ href: linkRoute.value.href,
147
+ target: props.target
148
+ }
149
+ : {}
150
+ )
123
151
  ))
124
152
 
125
153
  const linkActiveIndex = computed(() => {
126
- if (hasLink.value === false) {
154
+ if (hasRouterLink.value === false) {
127
155
  return null
128
156
  }
129
157
 
@@ -170,7 +198,7 @@ export default function () {
170
198
  })
171
199
 
172
200
  const linkIsActive = computed(() =>
173
- hasLink.value === true
201
+ hasRouterLink.value === true
174
202
  && linkActiveIndex.value > -1
175
203
  && includesParams(proxy.$route.params, linkRoute.value.params)
176
204
  )
@@ -182,7 +210,7 @@ export default function () {
182
210
  )
183
211
 
184
212
  const linkClass = computed(() => (
185
- hasLink.value === true
213
+ hasRouterLink.value === true
186
214
  ? (
187
215
  linkIsExactActive.value === true
188
216
  ? ` ${ props.exactActiveClass } ${ props.activeClass }`
@@ -195,18 +223,8 @@ export default function () {
195
223
  : ''
196
224
  ))
197
225
 
198
- const linkProps = computed(() => (
199
- hasLink.value === true
200
- ? {
201
- href: linkRoute.value.href,
202
- target: attrs.target,
203
- role: 'link'
204
- }
205
- : {}
206
- ))
207
-
208
226
  // should match RouterLink from Vue Router
209
- function navigateToLink (e) {
227
+ function navigateToRouterLink (e) {
210
228
  if (
211
229
  // component is not disabled
212
230
  props.disable === true
@@ -222,7 +240,7 @@ export default function () {
222
240
  || (e.button !== undefined && e.button !== 0)
223
241
 
224
242
  // don't redirect if it should open in a new window
225
- || attrs.target === '_blank'
243
+ || props.target === '_blank'
226
244
  ) {
227
245
  return false
228
246
  }
@@ -234,7 +252,10 @@ export default function () {
234
252
  }
235
253
 
236
254
  return {
255
+ hasRouterLink,
256
+ hasHrefLink,
237
257
  hasLink,
258
+
238
259
  linkTag,
239
260
  linkRoute,
240
261
  linkIsActive,
@@ -242,6 +263,6 @@ export default function () {
242
263
  linkClass,
243
264
  linkProps,
244
265
 
245
- navigateToLink
266
+ navigateToRouterLink
246
267
  }
247
268
  }