quasar 1.16.2 → 1.17.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (309) hide show
  1. package/dist/api/BottomSheet.json +2 -2
  2. package/dist/api/Loading.json +0 -2
  3. package/dist/api/LoadingBar.json +1 -1
  4. package/dist/api/Notify.json +25 -25
  5. package/dist/api/QAjaxBar.json +23 -4
  6. package/dist/api/QAvatar.json +1 -1
  7. package/dist/api/QBreadcrumbsEl.json +32 -11
  8. package/dist/api/QBtn.json +35 -14
  9. package/dist/api/QBtnDropdown.json +36 -15
  10. package/dist/api/QBtnToggle.json +1 -1
  11. package/dist/api/QCarousel.json +7 -7
  12. package/dist/api/QCarouselSlide.json +2 -2
  13. package/dist/api/QChatMessage.json +1 -5
  14. package/dist/api/QChip.json +4 -4
  15. package/dist/api/QColor.json +6 -0
  16. package/dist/api/QDialog.json +7 -1
  17. package/dist/api/QExpansionItem.json +34 -13
  18. package/dist/api/QFab.json +34 -2
  19. package/dist/api/QFabAction.json +9 -1
  20. package/dist/api/QField.json +80 -6
  21. package/dist/api/QFile.json +80 -6
  22. package/dist/api/QImg.json +2 -2
  23. package/dist/api/QInnerLoading.json +32 -0
  24. package/dist/api/QInput.json +82 -6
  25. package/dist/api/QItem.json +31 -10
  26. package/dist/api/QOptionGroup.json +58 -1
  27. package/dist/api/QPagination.json +4 -4
  28. package/dist/api/QParallax.json +1 -1
  29. package/dist/api/QPopupEdit.json +14 -7
  30. package/dist/api/QPullToRefresh.json +1 -1
  31. package/dist/api/QRange.json +581 -96
  32. package/dist/api/QRating.json +3 -3
  33. package/dist/api/QRouteTab.json +32 -12
  34. package/dist/api/QScrollArea.json +188 -20
  35. package/dist/api/QSelect.json +82 -10
  36. package/dist/api/QSeparator.json +1 -1
  37. package/dist/api/QSlider.json +499 -34
  38. package/dist/api/QStep.json +4 -4
  39. package/dist/api/QStepper.json +4 -4
  40. package/dist/api/QTab.json +1 -1
  41. package/dist/api/QTable.json +4 -4
  42. package/dist/api/QTabs.json +9 -0
  43. package/dist/api/QTimelineEntry.json +2 -2
  44. package/dist/api/QToggle.json +1 -1
  45. package/dist/api/QTree.json +7 -1
  46. package/dist/api/QVideo.json +10 -0
  47. package/dist/icon-set/bootstrap-icons.umd.min.js +1 -1
  48. package/dist/icon-set/eva-icons.umd.min.js +1 -1
  49. package/dist/icon-set/fontawesome-v5-pro.umd.min.js +1 -1
  50. package/dist/icon-set/fontawesome-v5.umd.min.js +1 -1
  51. package/dist/icon-set/ionicons-v4.umd.min.js +1 -1
  52. package/dist/icon-set/line-awesome.umd.min.js +1 -1
  53. package/dist/icon-set/material-icons-outlined.umd.min.js +1 -1
  54. package/dist/icon-set/material-icons-round.umd.min.js +1 -1
  55. package/dist/icon-set/material-icons-sharp.umd.min.js +1 -1
  56. package/dist/icon-set/material-icons.umd.min.js +1 -1
  57. package/dist/icon-set/mdi-v3.umd.min.js +1 -1
  58. package/dist/icon-set/mdi-v4.umd.min.js +1 -1
  59. package/dist/icon-set/mdi-v5.umd.min.js +1 -1
  60. package/dist/icon-set/mdi-v6.umd.min.js +1 -1
  61. package/dist/icon-set/svg-bootstrap-icons.umd.min.js +1 -1
  62. package/dist/icon-set/svg-eva-icons.umd.min.js +1 -1
  63. package/dist/icon-set/svg-fontawesome-v5.umd.min.js +1 -1
  64. package/dist/icon-set/svg-ionicons-v4.umd.min.js +1 -1
  65. package/dist/icon-set/svg-ionicons-v5.umd.min.js +1 -1
  66. package/dist/icon-set/svg-ionicons-v6.umd.min.js +6 -0
  67. package/dist/icon-set/svg-line-awesome.umd.min.js +1 -1
  68. package/dist/icon-set/svg-material-icons-outlined.umd.min.js +1 -1
  69. package/dist/icon-set/svg-material-icons-round.umd.min.js +1 -1
  70. package/dist/icon-set/svg-material-icons-sharp.umd.min.js +1 -1
  71. package/dist/icon-set/svg-material-icons.umd.min.js +1 -1
  72. package/dist/icon-set/svg-mdi-v4.umd.min.js +1 -1
  73. package/dist/icon-set/svg-mdi-v5.umd.min.js +1 -1
  74. package/dist/icon-set/svg-mdi-v6.umd.min.js +1 -1
  75. package/dist/icon-set/svg-themify.umd.min.js +1 -1
  76. package/dist/icon-set/themify.umd.min.js +1 -1
  77. package/dist/lang/ar.umd.min.js +2 -2
  78. package/dist/lang/az-latn.umd.min.js +1 -1
  79. package/dist/lang/bg.umd.min.js +1 -1
  80. package/dist/lang/ca.umd.min.js +1 -1
  81. package/dist/lang/cs.umd.min.js +1 -1
  82. package/dist/lang/da.umd.min.js +1 -1
  83. package/dist/lang/de.umd.min.js +1 -1
  84. package/dist/lang/el.umd.min.js +1 -1
  85. package/dist/lang/en-gb.umd.min.js +1 -1
  86. package/dist/lang/en-us.umd.min.js +1 -1
  87. package/dist/lang/eo.umd.min.js +1 -1
  88. package/dist/lang/es.umd.min.js +1 -1
  89. package/dist/lang/et.umd.min.js +1 -1
  90. package/dist/lang/fa-ir.umd.min.js +1 -1
  91. package/dist/lang/fa.umd.min.js +1 -1
  92. package/dist/lang/fi.umd.min.js +1 -1
  93. package/dist/lang/fr.umd.min.js +2 -2
  94. package/dist/lang/gn.umd.min.js +1 -1
  95. package/dist/lang/he.umd.min.js +1 -1
  96. package/dist/lang/hr.umd.min.js +1 -1
  97. package/dist/lang/hu.umd.min.js +1 -1
  98. package/dist/lang/id.umd.min.js +1 -1
  99. package/dist/lang/is.umd.min.js +1 -1
  100. package/dist/lang/it.umd.min.js +1 -1
  101. package/dist/lang/ja.umd.min.js +1 -1
  102. package/dist/lang/km.umd.min.js +1 -1
  103. package/dist/lang/ko-kr.umd.min.js +1 -1
  104. package/dist/lang/kur-ckb.umd.min.js +1 -1
  105. package/dist/lang/lu.umd.min.js +1 -1
  106. package/dist/lang/lv.umd.min.js +1 -1
  107. package/dist/lang/ml.umd.min.js +1 -1
  108. package/dist/lang/ms.umd.min.js +1 -1
  109. package/dist/lang/nb-no.umd.min.js +1 -1
  110. package/dist/lang/nl.umd.min.js +1 -1
  111. package/dist/lang/pl.umd.min.js +1 -1
  112. package/dist/lang/pt-br.umd.min.js +1 -1
  113. package/dist/lang/pt.umd.min.js +1 -1
  114. package/dist/lang/ro.umd.min.js +1 -1
  115. package/dist/lang/ru.umd.min.js +1 -1
  116. package/dist/lang/sk.umd.min.js +1 -1
  117. package/dist/lang/sl.umd.min.js +1 -1
  118. package/dist/lang/sr.umd.min.js +2 -2
  119. package/dist/lang/sv.umd.min.js +1 -1
  120. package/dist/lang/ta.umd.min.js +1 -1
  121. package/dist/lang/th.umd.min.js +1 -1
  122. package/dist/lang/tr.umd.min.js +1 -1
  123. package/dist/lang/ug.umd.min.js +2 -2
  124. package/dist/lang/uk.umd.min.js +1 -1
  125. package/dist/lang/vi.umd.min.js +1 -1
  126. package/dist/lang/zh-hans.umd.min.js +2 -2
  127. package/dist/lang/zh-hant.umd.min.js +2 -2
  128. package/dist/quasar.addon.css +1 -1
  129. package/dist/quasar.addon.rtl.css +1 -1
  130. package/dist/quasar.common.js +2 -2
  131. package/dist/quasar.css +378 -226
  132. package/dist/quasar.esm.js +2 -2
  133. package/dist/quasar.ie.polyfills.js +1 -1
  134. package/dist/quasar.ie.polyfills.umd.min.js +1 -1
  135. package/dist/quasar.min.css +1 -1
  136. package/dist/quasar.rtl.css +510 -302
  137. package/dist/quasar.rtl.min.css +1 -1
  138. package/dist/quasar.sass +326 -211
  139. package/dist/quasar.styl +326 -209
  140. package/dist/quasar.umd.js +3240 -1889
  141. package/dist/quasar.umd.min.js +2 -2
  142. package/dist/quasar.umd.modern.js +3199 -1870
  143. package/dist/quasar.umd.modern.min.js +2 -2
  144. package/dist/transform-asset-urls.json +20 -0
  145. package/dist/types/index.d.ts +427 -105
  146. package/dist/types/utils/scroll.d.ts +1 -0
  147. package/dist/vetur/quasar-attributes.json +320 -92
  148. package/dist/vetur/quasar-tags.json +76 -19
  149. package/dist/web-types/web-types.json +1296 -257
  150. package/icon-set/svg-ionicons-v6.js +225 -0
  151. package/lang/ar.js +1 -1
  152. package/lang/fa-ir.js +3 -1
  153. package/lang/fa.js +3 -1
  154. package/lang/fr.js +1 -1
  155. package/lang/index.json +1 -1
  156. package/lang/kur-ckb.js +2 -2
  157. package/lang/sr.js +4 -4
  158. package/lang/ug.js +48 -46
  159. package/lang/zh-hans.js +1 -1
  160. package/lang/zh-hant.js +18 -18
  161. package/package.json +1 -1
  162. package/src/api.extends.json +1 -2
  163. package/src/components/ajax-bar/QAjaxBar.js +48 -26
  164. package/src/components/ajax-bar/QAjaxBar.json +22 -4
  165. package/src/components/breadcrumbs/QBreadcrumbs.js +15 -11
  166. package/src/components/breadcrumbs/QBreadcrumbs.sass +0 -3
  167. package/src/components/breadcrumbs/QBreadcrumbs.styl +0 -3
  168. package/src/components/breadcrumbs/QBreadcrumbsEl.js +25 -9
  169. package/src/components/btn/QBtn.js +3 -3
  170. package/src/components/btn-dropdown/QBtnDropdown.sass +2 -0
  171. package/src/components/btn-dropdown/QBtnDropdown.styl +2 -0
  172. package/src/components/btn-toggle/QBtnToggle.js +4 -1
  173. package/src/components/carousel/QCarousel.js +6 -2
  174. package/src/components/carousel/QCarousel.json +9 -1
  175. package/src/components/carousel/QCarouselSlide.json +2 -2
  176. package/src/components/chat/QChatMessage.json +1 -1
  177. package/src/components/color/QColor.js +100 -85
  178. package/src/components/color/QColor.json +7 -0
  179. package/src/components/color/QColor.sass +14 -24
  180. package/src/components/color/QColor.styl +14 -24
  181. package/src/components/date/QDate.js +7 -1
  182. package/src/components/date/QDate.sass +2 -0
  183. package/src/components/date/QDate.styl +2 -0
  184. package/src/components/dialog/QDialog.js +8 -4
  185. package/src/components/dialog/QDialog.json +8 -1
  186. package/src/components/drawer/QDrawer.js +16 -15
  187. package/src/components/editor/QEditor.js +2 -2
  188. package/src/components/editor/QEditor.sass +13 -1
  189. package/src/components/editor/QEditor.styl +13 -1
  190. package/src/components/expansion-item/QExpansionItem.js +13 -11
  191. package/src/components/fab/QFab.js +20 -11
  192. package/src/components/fab/QFab.json +35 -0
  193. package/src/components/fab/QFabAction.js +16 -9
  194. package/src/components/fab/QFabAction.json +10 -0
  195. package/src/components/field/QField.js +28 -23
  196. package/src/components/field/__QField.json +72 -8
  197. package/src/components/file/QFile.js +12 -4
  198. package/src/components/file/QFile.sass +4 -3
  199. package/src/components/file/QFile.styl +4 -3
  200. package/src/components/footer/QFooter.js +1 -1
  201. package/src/components/form/QForm.js +1 -1
  202. package/src/components/header/QHeader.js +1 -1
  203. package/src/components/icon/QIcon.js +92 -75
  204. package/src/components/icon/QIcon.sass +0 -1
  205. package/src/components/icon/QIcon.styl +0 -1
  206. package/src/components/img/QImg.json +2 -2
  207. package/src/components/infinite-scroll/QInfiniteScroll.js +49 -36
  208. package/src/components/inner-loading/QInnerLoading.js +54 -22
  209. package/src/components/inner-loading/QInnerLoading.json +29 -0
  210. package/src/components/inner-loading/QInnerLoading.sass +3 -0
  211. package/src/components/inner-loading/QInnerLoading.styl +3 -0
  212. package/src/components/item/QItem.js +9 -15
  213. package/src/components/layout/QLayout.js +49 -0
  214. package/src/components/linear-progress/QLinearProgress.js +6 -2
  215. package/src/components/menu/QMenu.js +5 -1
  216. package/src/components/option-group/QOptionGroup.js +32 -22
  217. package/src/components/option-group/QOptionGroup.json +50 -1
  218. package/src/components/parallax/QParallax.js +3 -0
  219. package/src/components/parallax/QParallax.json +1 -1
  220. package/src/components/popup-edit/QPopupEdit.js +41 -16
  221. package/src/components/popup-edit/QPopupEdit.json +15 -8
  222. package/src/components/range/QRange.js +223 -278
  223. package/src/components/range/QRange.json +11 -122
  224. package/src/components/rating/QRating.js +56 -38
  225. package/src/components/rating/QRating.json +3 -3
  226. package/src/components/rating/QRating.sass +8 -6
  227. package/src/components/rating/QRating.styl +8 -6
  228. package/src/components/resize-observer/QResizeObserver.js +15 -10
  229. package/src/components/scroll-area/QScrollArea.js +342 -126
  230. package/src/components/scroll-area/QScrollArea.json +164 -20
  231. package/src/components/scroll-area/QScrollArea.sass +5 -0
  232. package/src/components/scroll-area/QScrollArea.styl +5 -0
  233. package/src/components/scroll-observer/QScrollObserver.js +9 -2
  234. package/src/components/select/QSelect.js +8 -2
  235. package/src/components/select/QSelect.json +1 -1
  236. package/src/components/separator/QSeparator.js +0 -1
  237. package/src/components/separator/QSeparator.json +1 -1
  238. package/src/components/slider/QSlider.js +97 -140
  239. package/src/components/slider/QSlider.json +1 -122
  240. package/src/components/slider/QSlider.sass +205 -139
  241. package/src/components/slider/QSlider.styl +205 -139
  242. package/src/components/slider/slider-utils.js +468 -123
  243. package/src/components/slider/slider-utils.json +546 -0
  244. package/src/components/stepper/QStepper.js +1 -1
  245. package/src/components/stepper/QStepper.sass +25 -26
  246. package/src/components/stepper/QStepper.styl +25 -26
  247. package/src/components/table/QTable.sass +3 -0
  248. package/src/components/table/QTable.styl +3 -0
  249. package/src/components/tabs/QRouteTab.js +13 -13
  250. package/src/components/tabs/QRouteTab.json +0 -7
  251. package/src/components/tabs/QTab.js +71 -20
  252. package/src/components/tabs/QTabs.js +237 -52
  253. package/src/components/tabs/QTabs.json +8 -0
  254. package/src/components/tabs/QTabs.sass +6 -6
  255. package/src/components/tabs/QTabs.styl +6 -6
  256. package/src/components/time/QTime.js +6 -2
  257. package/src/components/timeline/QTimeline.sass +1 -2
  258. package/src/components/timeline/QTimeline.styl +1 -2
  259. package/src/components/timeline/QTimelineEntry.json +1 -1
  260. package/src/components/tree/QTree.js +10 -6
  261. package/src/components/tree/QTree.json +5 -0
  262. package/src/components/tree/QTree.sass +58 -4
  263. package/src/components/tree/QTree.styl +58 -4
  264. package/src/components/uploader/QUploaderBase.js +15 -19
  265. package/src/components/video/QVideo.js +4 -1
  266. package/src/components/video/QVideo.json +11 -0
  267. package/src/components/virtual-scroll/QVirtualScroll.sass +1 -0
  268. package/src/components/virtual-scroll/QVirtualScroll.styl +1 -0
  269. package/src/css/core/helpers.sass +3 -0
  270. package/src/css/core/helpers.styl +3 -0
  271. package/src/css/core/positioning.sass +5 -0
  272. package/src/css/core/positioning.styl +5 -0
  273. package/src/css/normalize.sass +0 -7
  274. package/src/css/variables.sass +4 -6
  275. package/src/css/variables.styl +4 -6
  276. package/src/directives/Scroll.js +2 -2
  277. package/src/directives/ScrollFire.js +1 -0
  278. package/src/ie-compat/ie.js +13 -13
  279. package/src/install.js +1 -1
  280. package/src/lang.js +7 -4
  281. package/src/mixins/anchor.js +3 -13
  282. package/src/mixins/btn.js +33 -38
  283. package/src/mixins/btn.json +26 -11
  284. package/src/mixins/file.js +27 -5
  285. package/src/mixins/fullscreen.js +16 -4
  286. package/src/mixins/portal.js +10 -10
  287. package/src/mixins/router-link.js +88 -14
  288. package/src/mixins/router-link.json +26 -10
  289. package/src/mixins/validate.js +33 -15
  290. package/src/mixins/virtual-scroll.js +40 -42
  291. package/src/plugins/AppFullscreen.js +41 -16
  292. package/src/plugins/BottomSheet.json +1 -1
  293. package/src/plugins/Cookies.js +1 -1
  294. package/src/plugins/Loading.js +8 -0
  295. package/src/plugins/LoadingBar.js +9 -0
  296. package/src/plugins/LoadingBar.json +1 -1
  297. package/src/plugins/Notify.js +351 -333
  298. package/src/plugins/Notify.json +20 -20
  299. package/src/plugins/Notify.sass +9 -3
  300. package/src/plugins/Notify.styl +9 -3
  301. package/src/utils/clone.js +53 -4
  302. package/src/utils/date.js +134 -69
  303. package/src/utils/dom.js +28 -9
  304. package/src/utils/extend.js +2 -2
  305. package/src/utils/focus-manager.js +8 -10
  306. package/src/utils/global-dialog.js +18 -1
  307. package/src/utils/is.js +2 -2
  308. package/src/utils/morph.js +2 -12
  309. package/src/utils/scroll.js +71 -35
@@ -163,7 +163,7 @@ export default Vue.extend({
163
163
  'q-field--error': this.hasError,
164
164
 
165
165
  'q-field--readonly': this.readonly === true && this.disable !== true,
166
- [this.disable === true ? 'q-field--disabled' : 'q-validation-component']: true
166
+ 'q-field--disabled': this.disable === true
167
167
  }
168
168
  },
169
169
 
@@ -220,6 +220,17 @@ export default Vue.extend({
220
220
  }
221
221
  },
222
222
 
223
+ bottomSlotScope () {
224
+ return {
225
+ id: this.targetUid,
226
+ field: this.$el,
227
+ editable: this.editable,
228
+ focused: this.focused,
229
+ value: this.value,
230
+ errorMessage: this.computedErrorMessage
231
+ }
232
+ },
233
+
223
234
  attrs () {
224
235
  const attrs = {
225
236
  for: this.targetUid
@@ -238,19 +249,11 @@ export default Vue.extend({
238
249
 
239
250
  methods: {
240
251
  focus () {
241
- this.focusFn !== void 0 && removeFocusFn(this.focusFn)
242
- this.focusFn = addFocusFn(() => {
243
- if (this.showPopup !== void 0) {
244
- this.showPopup()
245
- return
246
- }
247
-
248
- this.__focus()
249
- })
252
+ addFocusFn(this.__focus)
250
253
  },
251
254
 
252
255
  blur () {
253
- this.focusFn !== void 0 && removeFocusFn(this.focusFn)
256
+ removeFocusFn(this.__focus)
254
257
  const el = document.activeElement
255
258
  // IE can have null document.activeElement
256
259
  if (el !== null && this.$el.contains(el)) {
@@ -393,24 +396,26 @@ export default Vue.extend({
393
396
  let msg, key
394
397
 
395
398
  if (this.hasError === true) {
396
- if (this.computedErrorMessage !== void 0) {
399
+ key = 'q--slot-error'
400
+
401
+ if (this.$scopedSlots.error !== void 0) {
402
+ msg = this.$scopedSlots.error(this.bottomSlotScope)
403
+ }
404
+ else if (this.computedErrorMessage !== void 0) {
397
405
  msg = [ h('div', { attrs: { role: 'alert' } }, [ this.computedErrorMessage ]) ]
398
406
  key = this.computedErrorMessage
399
407
  }
400
- else {
401
- msg = slot(this, 'error')
402
- key = 'q--slot-error'
403
- }
404
408
  }
405
409
  else if (this.hideHint !== true || this.focused === true) {
406
- if (this.hint !== void 0) {
410
+ key = 'q--slot-hint'
411
+
412
+ if (this.$scopedSlots.hint !== void 0) {
413
+ msg = this.$scopedSlots.hint(this.bottomSlotScope)
414
+ }
415
+ else if (this.hint !== void 0) {
407
416
  msg = [ h('div', [ this.hint ]) ]
408
417
  key = this.hint
409
418
  }
410
- else {
411
- msg = slot(this, 'hint')
412
- key = 'q--slot-hint'
413
- }
414
419
  }
415
420
 
416
421
  const hasCounter = this.counter === true || this.$scopedSlots.counter !== void 0
@@ -518,7 +523,7 @@ export default Vue.extend({
518
523
  this.$nextTick(() => {
519
524
  this.resetValidation()
520
525
 
521
- if (this.lazyRules !== 'ondemand' && this.$q.platform.is.mobile !== true) {
526
+ if (this.$q.platform.is.mobile !== true) {
522
527
  this.isDirty = false
523
528
  }
524
529
  })
@@ -534,7 +539,7 @@ export default Vue.extend({
534
539
  this.__onPostRender !== void 0 && this.$nextTick(this.__onPostRender)
535
540
 
536
541
  return h('label', {
537
- staticClass: 'q-field row no-wrap items-start',
542
+ staticClass: 'q-field q-validation-component row no-wrap items-start',
538
543
  class: this.classes,
539
544
  attrs: this.attrs
540
545
  }, [
@@ -209,14 +209,6 @@
209
209
  "addedIn": "v1.12.9"
210
210
  },
211
211
 
212
- "error": {
213
- "desc": "Slot for errors; Enabled only if 'bottom-slots' prop is used; Suggestion: <div>"
214
- },
215
-
216
- "hint": {
217
- "desc": "Slot for hint text; Enabled only if 'bottom-slots' prop is used; Suggestion: <div>"
218
- },
219
-
220
212
  "counter": {
221
213
  "desc": "Slot for counter text; Enabled only if 'bottom-slots' prop is used; Suggestion: <div>"
222
214
  },
@@ -226,6 +218,78 @@
226
218
  }
227
219
  },
228
220
 
221
+ "scopedSlots": {
222
+ "error": {
223
+ "desc": "Slot for errors; Enabled only if 'bottom-slots' prop is used; Suggestion: <div>",
224
+ "scope": {
225
+ "id": {
226
+ "type": "String",
227
+ "desc": "Element id used in the `for` attribute of the field label. Can be used to link the control to the label",
228
+ "examples": [ "qf_363270c0-7a83-62b1-8dcf-6dfd64ee38fa" ]
229
+ },
230
+ "field": {
231
+ "type": "Object",
232
+ "desc": "DOM element of the field",
233
+ "__exemption": [ "examples" ]
234
+ },
235
+ "editable": {
236
+ "type": "Boolean",
237
+ "desc": "Field is editable"
238
+ },
239
+ "focused": {
240
+ "type": "Boolean",
241
+ "desc": "Field has focus"
242
+ },
243
+ "value": {
244
+ "type": "Any",
245
+ "desc": "Field's value",
246
+ "examples": [ 0.241, "Text" ]
247
+ },
248
+ "errorMessage": {
249
+ "type": "String",
250
+ "desc": "Error message (from errorMessage prop or generated by rules)",
251
+ "examples": [ "The field is required" ]
252
+ }
253
+ },
254
+ "addedIn": "v1.17"
255
+ },
256
+
257
+ "hint": {
258
+ "desc": "Slot for hint text; Enabled only if 'bottom-slots' prop is used; Suggestion: <div>",
259
+ "scope": {
260
+ "id": {
261
+ "type": "String",
262
+ "desc": "Element id used in the `for` attribute of the field label. Can be used to link the control to the label",
263
+ "examples": [ "qf_363270c0-7a83-62b1-8dcf-6dfd64ee38fa" ]
264
+ },
265
+ "field": {
266
+ "type": "Object",
267
+ "desc": "DOM element of the field",
268
+ "__exemption": [ "examples" ]
269
+ },
270
+ "editable": {
271
+ "type": "Boolean",
272
+ "desc": "Field is editable"
273
+ },
274
+ "focused": {
275
+ "type": "Boolean",
276
+ "desc": "Field has focus"
277
+ },
278
+ "value": {
279
+ "type": "Any",
280
+ "desc": "Field's value",
281
+ "examples": [ 0.241, "Text" ]
282
+ },
283
+ "errorMessage": {
284
+ "type": "String",
285
+ "desc": "Error message (from errorMessage prop or generated by rules)",
286
+ "examples": [ "The field is required" ]
287
+ }
288
+ },
289
+ "addedIn": "v1.17"
290
+ }
291
+ },
292
+
229
293
  "events": {
230
294
  "clear": {
231
295
  "desc": "When using the 'clearable' property, this event is emitted when the clear icon is clicked",
@@ -9,6 +9,7 @@ import FileMixin, { FileValueMixin } from '../../mixins/file.js'
9
9
  import { isSSR } from '../../plugins/Platform'
10
10
  import { humanStorageSize } from '../../utils/format.js'
11
11
  import cache from '../../utils/cache.js'
12
+ import { prevent } from '../../utils/event.js'
12
13
 
13
14
  export default Vue.extend({
14
15
  name: 'QFile',
@@ -115,9 +116,16 @@ export default Vue.extend({
115
116
  this.$emit('input', this.multiple === true ? files : files[0])
116
117
  },
117
118
 
119
+ __onKeydown (e) {
120
+ // prevent form submit if ENTER is pressed
121
+ e.keyCode === 13 && prevent(e)
122
+ },
123
+
118
124
  __onKeyup (e) {
119
- // only on ENTER
120
- e.keyCode === 13 && this.pickFiles(e)
125
+ // only on ENTER and SPACE to match native input field
126
+ if (e.keyCode === 13 || e.keyCode === 32) {
127
+ this.pickFiles(e)
128
+ }
121
129
  },
122
130
 
123
131
  __getFileInput () {
@@ -159,6 +167,7 @@ export default Vue.extend({
159
167
  if (this.editable === true) {
160
168
  data.on = cache(this, 'native', {
161
169
  dragover: this.__onDragOver,
170
+ keydown: this.__onKeydown,
162
171
  keyup: this.__onKeyup
163
172
  })
164
173
  }
@@ -174,8 +183,7 @@ export default Vue.extend({
174
183
  return [
175
184
  h('input', {
176
185
  class: [ this.inputClass, 'q-file__filler' ],
177
- style: this.inputStyle,
178
- tabindex: -1
186
+ style: this.inputStyle
179
187
  })
180
188
  ]
181
189
  },
@@ -2,7 +2,6 @@
2
2
 
3
3
  .q-field__native
4
4
  word-break: break-all
5
- overflow: hidden
6
5
 
7
6
  .q-field__input
8
7
  opacity: 0 !important
@@ -11,8 +10,10 @@
11
10
  cursor: pointer
12
11
 
13
12
  &__filler
14
- opacity: 0
15
- pointer-events: none
13
+ visibility: hidden
14
+ width: 100%
15
+ border: none
16
+ padding: 0
16
17
 
17
18
  &__dnd
18
19
  outline: 1px dashed currentColor
@@ -2,7 +2,6 @@
2
2
 
3
3
  .q-field__native
4
4
  word-break: break-all
5
- overflow: hidden
6
5
 
7
6
  .q-field__input
8
7
  opacity: 0 !important
@@ -11,8 +10,10 @@
11
10
  cursor: pointer
12
11
 
13
12
  &__filler
14
- opacity: 0
15
- pointer-events: none
13
+ visibility: hidden
14
+ width: 100%
15
+ border: none
16
+ padding: 0
16
17
 
17
18
  &__dnd
18
19
  outline: 1px dashed currentColor
@@ -87,7 +87,7 @@ export default Vue.extend({
87
87
  fixed () {
88
88
  return this.reveal === true ||
89
89
  this.layout.view.indexOf('F') > -1 ||
90
- this.layout.container === true
90
+ (this.$q.platform.is.ios && this.layout.container === true)
91
91
  },
92
92
 
93
93
  containerHeight () {
@@ -42,7 +42,7 @@ export default Vue.extend({
42
42
 
43
43
  this.validateIndex++
44
44
 
45
- const components = this.getValidationComponents()
45
+ const components = this.getValidationComponents().filter(c => c.disable !== true)
46
46
 
47
47
  const emit = (res, ref) => {
48
48
  this.$emit('validation-' + (res === true ? 'success' : 'error'), ref)
@@ -80,7 +80,7 @@ export default Vue.extend({
80
80
  fixed () {
81
81
  return this.reveal === true ||
82
82
  this.layout.view.indexOf('H') > -1 ||
83
- this.layout.container === true
83
+ (this.$q.platform.is.ios && this.layout.container === true)
84
84
  },
85
85
 
86
86
  offset () {
@@ -6,6 +6,38 @@ import ListenersMixin from '../../mixins/listeners.js'
6
6
 
7
7
  import { slot, mergeSlot } from '../../utils/slot.js'
8
8
 
9
+ const defaultViewBox = '0 0 24 24'
10
+
11
+ const sameFn = i => i
12
+ const ionFn = i => `ionicons ${i}`
13
+
14
+ const libMap = {
15
+ 'icon-': sameFn, // fontawesome equiv
16
+ 'bt-': i => `bt ${i}`,
17
+ 'eva-': i => `eva ${i}`,
18
+ 'ion-md': ionFn,
19
+ 'ion-ios': ionFn,
20
+ 'ion-logo': ionFn,
21
+ 'mdi-': i => `mdi ${i}`,
22
+ 'iconfont ': sameFn,
23
+ 'ti-': i => `themify-icon ${i}`,
24
+ 'bi-': i => `bootstrap-icons ${i}`
25
+ }
26
+
27
+ const matMap = {
28
+ o_: '-outlined',
29
+ r_: '-round',
30
+ s_: '-sharp'
31
+ }
32
+
33
+ const libRE = new RegExp('^(' + Object.keys(libMap).join('|') + ')')
34
+ const matRE = new RegExp('^(' + Object.keys(matMap).join('|') + ')')
35
+ const mRE = /^[Mm]\s?[-+]?\.?\d/
36
+ const imgRE = /^img:/
37
+ const svgUseRE = /^svguse:/
38
+ const ionRE = /^ion-/
39
+ const faLaRE = /^[lf]a[srlbdk]? /
40
+
9
41
  export default Vue.extend({
10
42
  name: 'QIcon',
11
43
 
@@ -13,6 +45,7 @@ export default Vue.extend({
13
45
 
14
46
  props: {
15
47
  tag: {
48
+ type: String,
16
49
  default: 'i'
17
50
  },
18
51
 
@@ -24,9 +57,7 @@ export default Vue.extend({
24
57
 
25
58
  computed: {
26
59
  classes () {
27
- // "notranslate" class is for Google Translate
28
- // to avoid tampering with Material Icons ligature font
29
- return 'q-icon notranslate' +
60
+ return 'q-icon' +
30
61
  (this.left === true ? ' on-left' : '') +
31
62
  (this.right === true ? ' on-right' : '') +
32
63
  (this.color !== void 0 ? ` text-${this.color}` : '')
@@ -37,10 +68,7 @@ export default Vue.extend({
37
68
  let icon = this.name
38
69
 
39
70
  if (!icon) {
40
- return {
41
- none: true,
42
- cls: this.classes
43
- }
71
+ return { none: true }
44
72
  }
45
73
 
46
74
  if (this.$q.iconMapFn !== void 0) {
@@ -51,7 +79,7 @@ export default Vue.extend({
51
79
  }
52
80
  else {
53
81
  return {
54
- cls: res.cls + ' ' + this.classes,
82
+ cls: res.cls,
55
83
  content: res.content !== void 0
56
84
  ? res.content
57
85
  : ' '
@@ -60,95 +88,70 @@ export default Vue.extend({
60
88
  }
61
89
  }
62
90
 
63
- if (icon.startsWith('M') === true) {
64
- const [ def, viewBox ] = icon.split('|')
91
+ if (mRE.test(icon) === true) {
92
+ const [ def, viewBox = defaultViewBox ] = icon.split('|')
65
93
 
66
94
  return {
67
95
  svg: true,
68
- cls: this.classes,
96
+ viewBox,
69
97
  nodes: def.split('&&').map(path => {
70
98
  const [ d, style, transform ] = path.split('@@')
71
99
  return this.$createElement('path', {
72
- attrs: {
73
- d,
74
- transform
75
- },
100
+ attrs: { d, transform },
76
101
  style
77
102
  })
78
- }),
79
- viewBox: viewBox !== void 0 ? viewBox : '0 0 24 24'
103
+ })
80
104
  }
81
105
  }
82
106
 
83
- if (icon.startsWith('img:') === true) {
107
+ if (imgRE.test(icon) === true) {
84
108
  return {
85
109
  img: true,
86
- cls: this.classes,
87
110
  src: icon.substring(4)
88
111
  }
89
112
  }
90
113
 
91
- if (icon.startsWith('svguse:') === true) {
92
- const [ def, viewBox ] = icon.split('|')
114
+ if (svgUseRE.test(icon) === true) {
115
+ const [ def, viewBox = defaultViewBox ] = icon.split('|')
93
116
 
94
117
  return {
95
118
  svguse: true,
96
- cls: this.classes,
97
119
  src: def.substring(7),
98
- viewBox: viewBox !== void 0 ? viewBox : '0 0 24 24'
120
+ viewBox
99
121
  }
100
122
  }
101
123
 
102
124
  let content = ' '
125
+ const matches = icon.match(libRE)
103
126
 
104
- if (/^[l|f]a[s|r|l|b|d]{0,1} /.test(icon) || icon.startsWith('icon-') === true) {
105
- cls = icon
106
- }
107
- else if (icon.startsWith('bt-') === true) {
108
- cls = `bt ${icon}`
109
- }
110
- else if (icon.startsWith('eva-') === true) {
111
- cls = `eva ${icon}`
127
+ if (matches !== null) {
128
+ cls = libMap[ matches[ 1 ] ](icon)
112
129
  }
113
- else if (/^ion-(md|ios|logo)/.test(icon) === true) {
114
- cls = `ionicons ${icon}`
130
+ else if (faLaRE.test(icon) === true) {
131
+ cls = icon
115
132
  }
116
- else if (icon.startsWith('ion-') === true) {
133
+ else if (ionRE.test(icon) === true) {
117
134
  cls = `ionicons ion-${this.$q.platform.is.ios === true ? 'ios' : 'md'}${icon.substr(3)}`
118
135
  }
119
- else if (icon.startsWith('mdi-') === true) {
120
- cls = `mdi ${icon}`
121
- }
122
- else if (icon.startsWith('iconfont ') === true) {
123
- cls = `${icon}`
124
- }
125
- else if (icon.startsWith('ti-') === true) {
126
- cls = `themify-icon ${icon}`
127
- }
128
- else if (icon.startsWith('bi-') === true) {
129
- cls = `bootstrap-icons ${icon}`
130
- }
131
136
  else {
132
- cls = 'material-icons'
133
-
134
- if (icon.startsWith('o_') === true) {
137
+ // "notranslate" class is for Google Translate
138
+ // to avoid tampering with Material Icons ligature font
139
+ //
140
+ // Caution: To be able to add suffix to the class name,
141
+ // keep the 'material-icons' at the end of the string.
142
+ cls = 'notranslate material-icons'
143
+
144
+ const matches = icon.match(matRE)
145
+ if (matches !== null) {
135
146
  icon = icon.substring(2)
136
- cls += '-outlined'
137
- }
138
- else if (icon.startsWith('r_') === true) {
139
- icon = icon.substring(2)
140
- cls += '-round'
141
- }
142
- else if (icon.startsWith('s_') === true) {
143
- icon = icon.substring(2)
144
- cls += '-sharp'
147
+ cls += matMap[ matches[ 1 ] ]
145
148
  }
146
149
 
147
150
  content = icon
148
151
  }
149
152
 
150
153
  return {
151
- cls: cls + ' ' + this.classes,
154
+ cls,
152
155
  content
153
156
  }
154
157
  }
@@ -156,7 +159,7 @@ export default Vue.extend({
156
159
 
157
160
  render (h) {
158
161
  const data = {
159
- class: this.type.cls,
162
+ class: this.classes,
160
163
  style: this.sizeStyle,
161
164
  on: { ...this.qListeners },
162
165
  attrs: {
@@ -170,28 +173,42 @@ export default Vue.extend({
170
173
  }
171
174
 
172
175
  if (this.type.img === true) {
173
- data.attrs.src = this.type.src
174
- return h('img', data)
176
+ return h('div', data, mergeSlot([
177
+ h('img', {
178
+ class: this.type.cls,
179
+ attrs: { src: this.type.src }
180
+ })
181
+ ], this, 'default'))
175
182
  }
176
183
 
177
184
  if (this.type.svg === true) {
178
- data.attrs.focusable = 'false' /* needed for IE11 */
179
- data.attrs.viewBox = this.type.viewBox
180
-
181
- return h('svg', data, mergeSlot(this.type.nodes, this, 'default'))
185
+ return h('div', data, mergeSlot([
186
+ h('svg', {
187
+ class: this.type.cls,
188
+ attrs: {
189
+ viewBox: this.type.viewBox,
190
+ focusable: 'false' /* needed for IE11 */
191
+ }
192
+ }, this.type.nodes)
193
+ ], this, 'default'))
182
194
  }
183
- if (this.type.svguse === true) {
184
- data.attrs.focusable = 'false' /* needed for IE11 */
185
- data.attrs.viewBox = this.type.viewBox
186
195
 
187
- return h('svg', data, [
188
- h('use', {
196
+ if (this.type.svguse === true) {
197
+ return h('div', data, mergeSlot([
198
+ h('svg', {
199
+ class: this.type.cls,
189
200
  attrs: {
190
- 'xlink:href': this.type.src
201
+ viewBox: this.type.viewBox,
202
+ focusable: 'false' /* needed for IE11 */
191
203
  }
192
- }),
193
- mergeSlot(this.type.nodes, this, 'default')
194
- ])
204
+ }, [
205
+ h('use', { attrs: { 'xlink:href': this.type.src } })
206
+ ])
207
+ ], this, 'default'))
208
+ }
209
+
210
+ if (this.type.cls !== void 0) {
211
+ data.class += ' ' + this.type.cls
195
212
  }
196
213
 
197
214
  return h(this.tag, data, mergeSlot([
@@ -10,7 +10,6 @@
10
10
  text-align: center
11
11
  position: relative
12
12
  box-sizing: content-box
13
-
14
13
  fill: currentColor // for svg paths
15
14
 
16
15
  &:before, &:after
@@ -10,7 +10,6 @@
10
10
  text-align: center
11
11
  position: relative
12
12
  box-sizing: content-box
13
-
14
13
  fill: currentColor // for svg paths
15
14
 
16
15
  &:before, &:after
@@ -15,7 +15,7 @@
15
15
  "desc": "Path to image",
16
16
  "transformAssetUrls": true,
17
17
  "examples": [
18
- "(statics folder) src=\"statics/img/something.png\"",
18
+ "(public folder) src=\"img/something.png\"",
19
19
  "(assets folder) src=\"~assets/my-img.gif\"",
20
20
  "(relative path format) :src=\"require('./my_img.jpg')\"",
21
21
  "(URL) src=\"https://placeimg.com/500/300/nature\""
@@ -77,7 +77,7 @@
77
77
  "desc": "While waiting for your image to load, you can use a placeholder image",
78
78
  "transformAssetUrls": true,
79
79
  "examples": [
80
- "(statics folder) src=\"statics/img/some-placeholder.png\"",
80
+ "(public folder) src=\"img/some-placeholder.png\"",
81
81
  "(assets folder) src=\"~assets/my-placeholder.gif\"",
82
82
  "(relative path format) :src=\"require('./placeholder.jpg')\"",
83
83
  "(URL) src=\"https://placeimg.com/500/300/nature\""