quasar 1.16.3 → 1.17.3

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 (308) 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 +380 -227
  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 +512 -303
  137. package/dist/quasar.rtl.min.css +1 -1
  138. package/dist/quasar.sass +328 -210
  139. package/dist/quasar.styl +328 -210
  140. package/dist/quasar.umd.js +3244 -1894
  141. package/dist/quasar.umd.min.js +2 -2
  142. package/dist/quasar.umd.modern.js +3199 -1875
  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 +89 -75
  204. package/src/components/icon/QIcon.sass +2 -2
  205. package/src/components/icon/QIcon.styl +2 -2
  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 +12 -7
  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/variables.sass +4 -6
  274. package/src/css/variables.styl +4 -6
  275. package/src/directives/Scroll.js +2 -2
  276. package/src/directives/ScrollFire.js +1 -0
  277. package/src/ie-compat/ie.js +13 -13
  278. package/src/install.js +1 -1
  279. package/src/lang.js +7 -4
  280. package/src/mixins/anchor.js +3 -13
  281. package/src/mixins/btn.js +33 -38
  282. package/src/mixins/btn.json +26 -11
  283. package/src/mixins/file.js +27 -5
  284. package/src/mixins/fullscreen.js +16 -4
  285. package/src/mixins/portal.js +10 -10
  286. package/src/mixins/router-link.js +88 -14
  287. package/src/mixins/router-link.json +26 -10
  288. package/src/mixins/validate.js +33 -15
  289. package/src/mixins/virtual-scroll.js +40 -42
  290. package/src/plugins/AppFullscreen.js +41 -16
  291. package/src/plugins/BottomSheet.json +1 -1
  292. package/src/plugins/Cookies.js +1 -1
  293. package/src/plugins/Loading.js +8 -0
  294. package/src/plugins/LoadingBar.js +9 -0
  295. package/src/plugins/LoadingBar.json +1 -1
  296. package/src/plugins/Notify.js +351 -333
  297. package/src/plugins/Notify.json +20 -20
  298. package/src/plugins/Notify.sass +9 -3
  299. package/src/plugins/Notify.styl +9 -3
  300. package/src/utils/clone.js +53 -4
  301. package/src/utils/date.js +134 -69
  302. package/src/utils/dom.js +28 -9
  303. package/src/utils/extend.js +2 -2
  304. package/src/utils/focus-manager.js +8 -10
  305. package/src/utils/global-dialog.js +18 -1
  306. package/src/utils/is.js +2 -2
  307. package/src/utils/morph.js +2 -12
  308. package/src/utils/scroll.js +71 -35
@@ -9,6 +9,7 @@ import ListenersMixin from '../../mixins/listeners.js'
9
9
  import { stop, noop } from '../../utils/event.js'
10
10
  import { slot } from '../../utils/slot.js'
11
11
  import cache from '../../utils/cache.js'
12
+ import { rtlHasScrollBug } from '../../utils/scroll.js'
12
13
 
13
14
  function getIndicatorClass (color, top, vertical) {
14
15
  const pos = vertical === true
@@ -53,7 +54,8 @@ export default Vue.extend({
53
54
  tabs: this.tabs,
54
55
  __recalculateScroll: this.__recalculateScroll,
55
56
  __activateTab: this.__activateTab,
56
- __activateRoute: this.__activateRoute
57
+ __activateRoute: this.__activateRoute,
58
+ __onKbdNavigate: this.__onKbdNavigate
57
59
  }
58
60
  },
59
61
 
@@ -74,6 +76,7 @@ export default Vue.extend({
74
76
  shrink: Boolean,
75
77
  stretch: Boolean,
76
78
 
79
+ activeClass: String,
77
80
  activeColor: String,
78
81
  activeBgColor: String,
79
82
  indicatorColor: String,
@@ -98,6 +101,8 @@ export default Vue.extend({
98
101
  return {
99
102
  tabs: {
100
103
  current: this.value,
104
+ hasFocus: false,
105
+ activeClass: this.activeClass,
101
106
  activeColor: this.activeColor,
102
107
  activeBgColor: this.activeBgColor,
103
108
  indicatorClass: getIndicatorClass(
@@ -110,8 +115,8 @@ export default Vue.extend({
110
115
  noCaps: this.noCaps
111
116
  },
112
117
  scrollable: false,
113
- leftArrow: true,
114
- rightArrow: false,
118
+ startArrow: true,
119
+ endArrow: false,
115
120
  justify: false
116
121
  }
117
122
  },
@@ -121,6 +126,10 @@ export default Vue.extend({
121
126
  this.__activateTab(name, true, true)
122
127
  },
123
128
 
129
+ activeClass (v) {
130
+ this.tabs.activeClass = v
131
+ },
132
+
124
133
  activeColor (v) {
125
134
  this.tabs.activeColor = v
126
135
  },
@@ -154,7 +163,7 @@ export default Vue.extend({
154
163
  },
155
164
 
156
165
  outsideArrows () {
157
- this.$nextTick(this.__recalculateScroll())
166
+ this.__recalculateScroll()
158
167
  },
159
168
 
160
169
  arrowsEnabled (v) {
@@ -162,7 +171,11 @@ export default Vue.extend({
162
171
  ? this.__updateArrowsFn
163
172
  : noop
164
173
 
165
- this.$nextTick(this.__recalculateScroll())
174
+ this.__recalculateScroll()
175
+ },
176
+
177
+ isRTL () {
178
+ this.__updateArrows()
166
179
  }
167
180
  },
168
181
 
@@ -171,6 +184,17 @@ export default Vue.extend({
171
184
  return this.$q.platform.is.desktop === true || this.mobileArrows === true
172
185
  },
173
186
 
187
+ arrowIcons () {
188
+ const sides = this.isRTL === true
189
+ ? [ 'end', 'start' ]
190
+ : [ 'start', 'end' ]
191
+
192
+ return {
193
+ [sides[0]]: this.leftIcon || (this.vertical === true ? this.$q.iconSet.tabs.up : this.$q.iconSet.tabs.left),
194
+ [sides[1]]: this.rightIcon || (this.vertical === true ? this.$q.iconSet.tabs.down : this.$q.iconSet.tabs.right)
195
+ }
196
+ },
197
+
174
198
  alignClass () {
175
199
  const align = this.scrollable === true
176
200
  ? 'left'
@@ -200,15 +224,69 @@ export default Vue.extend({
200
224
  : { container: 'width', content: 'offsetWidth', scroll: 'scrollWidth' }
201
225
  },
202
226
 
227
+ isRTL () {
228
+ return this.vertical !== true && this.$q.lang.rtl === true
229
+ },
230
+
231
+ __getScrollPosition () {
232
+ return this.vertical === true
233
+ ? el => el.scrollTop
234
+ : (
235
+ this.$q.lang.rtl !== true
236
+ ? el => el.scrollLeft
237
+ : (
238
+ this.rtlHasScrollBug === true
239
+ ? el => el.scrollWidth - el.clientWidth - el.scrollLeft
240
+ : el => 1 - el.scrollLeft
241
+ )
242
+ )
243
+ },
244
+
245
+ __setScrollPosition () {
246
+ return this.vertical === true
247
+ ? (el, value) => { el.scrollTop = value }
248
+ : (
249
+ this.$q.lang.rtl !== true
250
+ ? (el, value) => { el.scrollLeft = value }
251
+ : (
252
+ this.rtlHasScrollBug === true
253
+ ? (el, value) => { el.scrollLeft = el.scrollWidth - el.clientWidth - value }
254
+ : (el, value) => { el.scrollLeft = 1 - value }
255
+ )
256
+ )
257
+ },
258
+
259
+ __getScrollOffset () {
260
+ return this.vertical === true
261
+ ? el => el.offsetTop
262
+ : (
263
+ this.$q.lang.rtl !== true || this.rtlHasScrollBug === true
264
+ ? el => el.offsetLeft
265
+ : el => el.offsetParent.offsetWidth - el.offsetLeft - el.clientWidth
266
+ )
267
+ },
268
+
203
269
  onEvents () {
204
270
  return {
205
271
  input: stop,
206
- ...this.qListeners
272
+ ...this.qListeners,
273
+ focusin: this.__onFocusin,
274
+ focusout: this.__onFocusout
207
275
  }
208
276
  }
209
277
  },
210
278
 
211
279
  methods: {
280
+ __onFocusin (e) {
281
+ this.tabs.hasFocus = true
282
+ this.qListeners.focusin !== void 0 && this.$emit('focusin', e)
283
+ },
284
+
285
+ __onFocusout (e) {
286
+ this.tabs.hasFocus = false
287
+ this.qListeners.focusout !== void 0 && this.$emit('focusout', e)
288
+ },
289
+
212
290
  __activateTab (name, setCurrent, skipEmit) {
213
291
  if (this.tabs.current !== name) {
214
292
  skipEmit !== true && this.$emit('input', name)
@@ -270,7 +348,7 @@ export default Vue.extend({
270
348
  this.$refs.content[this.domProps.scroll],
271
349
  Array.prototype.reduce.call(
272
350
  this.$refs.content.children,
273
- (acc, el) => acc + el[this.domProps.content],
351
+ (acc, el) => acc + (el[this.domProps.content] || 0),
274
352
  0
275
353
  )
276
354
  ),
@@ -329,40 +407,32 @@ export default Vue.extend({
329
407
  }
330
408
 
331
409
  if (newTab && this.scrollable === true) {
332
- const
333
- { left, width, top, height } = this.$refs.content.getBoundingClientRect(),
334
- newPos = newTab.$el.getBoundingClientRect()
335
-
336
- let offset = this.vertical === true ? newPos.top - top : newPos.left - left
337
-
338
- if (offset < 0) {
339
- this.$refs.content[this.vertical === true ? 'scrollTop' : 'scrollLeft'] += Math.floor(offset)
340
- this.__updateArrows()
341
- return
342
- }
343
-
344
- offset += this.vertical === true ? newPos.height - height : newPos.width - width
345
- if (offset > 0) {
346
- this.$refs.content[this.vertical === true ? 'scrollTop' : 'scrollLeft'] += Math.ceil(offset)
347
- this.__updateArrows()
348
- }
410
+ this.__scrollToTab(newTab.$el, void 0, true)
411
+ }
412
+ else {
413
+ this.__updateArrows()
349
414
  }
350
415
  },
351
416
 
352
417
  __updateArrowsFn () {
353
- const
354
- content = this.$refs.content,
355
- rect = content.getBoundingClientRect(),
356
- pos = this.vertical === true ? content.scrollTop : content.scrollLeft
418
+ const { content } = this.$refs
419
+
420
+ if (content !== void 0) {
421
+ const
422
+ rect = content.getBoundingClientRect(),
423
+ pos = this.__getScrollPosition(content)
357
424
 
358
- this.leftArrow = pos > 0
359
- this.rightArrow = this.vertical === true
360
- ? Math.ceil(pos + rect.height) < content.scrollHeight
361
- : Math.ceil(pos + rect.width) < content.scrollWidth
425
+ this.startArrow = pos > (this.isRTL === true ? 1 : 0)
426
+ this.endArrow = this.vertical === true
427
+ ? Math.ceil(pos + rect.height) < content.scrollHeight
428
+ : Math.ceil(pos + rect.width) < content.scrollWidth
429
+ }
362
430
  },
363
431
 
364
- __animScrollTo (value) {
432
+ __animScrollTo (value, onEnd) {
365
433
  this.__stopAnimScroll()
434
+
435
+ this.__onAnimScrollEnd = onEnd
366
436
  this.__scrollTowards(value)
367
437
 
368
438
  this.scrollTimer = setInterval(() => {
@@ -377,26 +447,32 @@ export default Vue.extend({
377
447
  },
378
448
 
379
449
  __scrollToEnd () {
380
- this.__animScrollTo(9999)
450
+ this.__animScrollTo(Number.MAX_SAFE_INTEGER)
381
451
  },
382
452
 
383
453
  __stopAnimScroll () {
384
454
  clearInterval(this.scrollTimer)
455
+
456
+ if (this.__onAnimScrollEnd !== void 0) {
457
+ this.__onAnimScrollEnd()
458
+ this.__onAnimScrollEnd = void 0
459
+ }
385
460
  },
386
461
 
387
462
  __scrollTowards (value) {
388
463
  const content = this.$refs.content
389
- let
390
- pos = this.vertical === true ? content.scrollTop : content.scrollLeft,
391
- done = false
464
+ const max = this.vertical === true ? content.scrollHeight - content.offsetHeight : content.scrollWidth - content.offsetWidth
465
+
466
+ let pos = this.__getScrollPosition(content)
467
+ let done = false
468
+
469
+ value = Math.max(0, Math.min(max, value))
470
+
392
471
  const direction = value < pos ? -1 : 1
393
472
 
394
473
  pos += direction * 5
395
- if (pos < 0) {
396
- done = true
397
- pos = 0
398
- }
399
- else if (
474
+
475
+ if (
400
476
  (direction === -1 && pos <= value) ||
401
477
  (direction === 1 && pos >= value)
402
478
  ) {
@@ -404,9 +480,113 @@ export default Vue.extend({
404
480
  pos = value
405
481
  }
406
482
 
407
- content[this.vertical === true ? 'scrollTop' : 'scrollLeft'] = pos
483
+ this.__setScrollPosition(content, pos)
408
484
  this.__updateArrows()
485
+
409
486
  return done
487
+ },
488
+
489
+ __scrollToTab (tab, alignEnd, skipFocus) {
490
+ if (this.$refs.content === void 0) {
491
+ return
492
+ }
493
+
494
+ const content = this.$refs.content
495
+ const startContent = this.__getScrollPosition(content)
496
+ const sizeContent = this.vertical === true ? content.offsetHeight : content.offsetWidth
497
+ const sizeScroll = this.vertical === true ? content.scrollHeight : content.scrollWidth
498
+
499
+ const startTab = this.__getScrollOffset(tab)
500
+ const endTab = startTab + (this.vertical === true ? tab.offsetHeight : tab.offsetWidth)
501
+
502
+ const startsBefore = startTab < startContent
503
+ const endsAfter = endTab > startContent + sizeContent
504
+
505
+ if (startsBefore !== true && endsAfter !== true) {
506
+ alignEnd = void 0
507
+ }
508
+ else if (alignEnd === void 0) {
509
+ if (endTab >= sizeScroll - 1) {
510
+ alignEnd = true
511
+ }
512
+ else if (startsBefore === true || (endsAfter === true && startTab < endTab - sizeContent)) {
513
+ alignEnd = false
514
+ }
515
+ else if (startsBefore !== endsAfter) {
516
+ alignEnd = endsAfter
517
+ }
518
+ }
519
+
520
+ if (alignEnd !== void 0) {
521
+ this.__animScrollTo(
522
+ alignEnd === true ? (endTab >= sizeScroll - 1 ? sizeScroll : endTab - sizeContent) : (startTab <= 1 ? 0 : startTab),
523
+ skipFocus !== true
524
+ ? () => {
525
+ setTimeout(() => {
526
+ tab && tab.focus()
527
+ })
528
+ }
529
+ : void 0
530
+ )
531
+ }
532
+ else if (skipFocus !== true) {
533
+ tab.focus()
534
+ }
535
+ },
536
+
537
+ __onKbdNavigate (keyCode, fromEl) {
538
+ const matchTab = el => el === fromEl || (el.matches && el.matches('.q-tab.q-focusable') === true)
539
+ const tabs = Array.prototype.filter.call(this.$refs.content.children, matchTab)
540
+ const tabsLength = tabs.length
541
+
542
+ if (tabsLength === 0) {
543
+ return
544
+ }
545
+
546
+ if (keyCode === 36) { // Home
547
+ if (tabs[0].contains(document.activeElement) === true) {
548
+ return false
549
+ }
550
+
551
+ this.__scrollToTab(tabs[0], false)
552
+ this.__recalculateScroll()
553
+
554
+ return true
555
+ }
556
+ if (keyCode === 35) { // End
557
+ if (tabs[tabsLength - 1].contains(document.activeElement) === true) {
558
+ return false
559
+ }
560
+
561
+ this.__scrollToTab(tabs[tabsLength - 1], true)
562
+ this.__recalculateScroll()
563
+
564
+ return true
565
+ }
566
+
567
+ const dirPrev = (this.vertical === true && keyCode === 38 /* ArrowUp */) ||
568
+ (this.vertical !== true && keyCode === 37 /* ArrowLeft */)
569
+ const dirNext = (this.vertical === true && keyCode === 40 /* ArrowDown */) ||
570
+ (this.vertical !== true && keyCode === 39 /* ArrowRight */)
571
+ const dir = dirPrev === true ? -1 : (dirNext === true ? 1 : void 0)
572
+
573
+ if (dir !== void 0) {
574
+ const rtlDir = this.isRTL === true ? -1 : 1
575
+ const index = tabs.indexOf(fromEl) + dir * rtlDir
576
+
577
+ if (
578
+ index < 0 ||
579
+ index >= tabsLength ||
580
+ tabs[index].contains(document.activeElement) === true
581
+ ) {
582
+ return false
583
+ }
584
+
585
+ this.__scrollToTab(tabs[index], dir === rtlDir)
586
+ this.__recalculateScroll()
587
+
588
+ return true
589
+ }
410
590
  }
411
591
  },
412
592
 
@@ -416,11 +596,16 @@ export default Vue.extend({
416
596
 
417
597
  created () {
418
598
  this.buffer = []
599
+
419
600
  this.__updateArrows = this.arrowsEnabled === true
420
601
  ? this.__updateArrowsFn
421
602
  : noop
422
603
  },
423
604
 
605
+ mounted () {
606
+ this.rtlHasScrollBug = rtlHasScrollBug()
607
+ },
608
+
424
609
  beforeDestroy () {
425
610
  clearTimeout(this.bufferTimer)
426
611
  clearTimeout(this.animateTimer)
@@ -434,7 +619,7 @@ export default Vue.extend({
434
619
 
435
620
  h('div', {
436
621
  ref: 'content',
437
- staticClass: 'q-tabs__content row no-wrap items-center self-stretch hide-scrollbar',
622
+ staticClass: 'q-tabs__content row no-wrap items-center self-stretch hide-scrollbar relative-position',
438
623
  class: this.innerClass,
439
624
  on: this.arrowsEnabled === true ? cache(this, 'scroll', { scroll: this.__updateArrowsFn }) : void 0
440
625
  }, slot(this, 'default'))
@@ -442,10 +627,10 @@ export default Vue.extend({
442
627
 
443
628
  this.arrowsEnabled === true && child.push(
444
629
  h(QIcon, {
445
- staticClass: 'q-tabs__arrow q-tabs__arrow--left absolute q-tab__icon',
446
- class: this.leftArrow === true ? '' : 'q-tabs__arrow--faded',
447
- props: { name: this.leftIcon || (this.vertical === true ? this.$q.iconSet.tabs.up : this.$q.iconSet.tabs.left) },
448
- on: cache(this, 'onL', {
630
+ staticClass: 'q-tabs__arrow q-tabs__arrow--start absolute q-tab__icon',
631
+ class: this.startArrow === true ? '' : 'q-tabs__arrow--faded',
632
+ props: { name: this.arrowIcons.start },
633
+ on: cache(this, 'onS', {
449
634
  mousedown: this.__scrollToStart,
450
635
  touchstart: this.__scrollToStart,
451
636
  mouseup: this.__stopAnimScroll,
@@ -455,10 +640,10 @@ export default Vue.extend({
455
640
  }),
456
641
 
457
642
  h(QIcon, {
458
- staticClass: 'q-tabs__arrow q-tabs__arrow--right absolute q-tab__icon',
459
- class: this.rightArrow === true ? '' : 'q-tabs__arrow--faded',
460
- props: { name: this.rightIcon || (this.vertical === true ? this.$q.iconSet.tabs.down : this.$q.iconSet.tabs.right) },
461
- on: cache(this, 'onR', {
643
+ staticClass: 'q-tabs__arrow q-tabs__arrow--end absolute q-tab__icon',
644
+ class: this.endArrow === true ? '' : 'q-tabs__arrow--faded',
645
+ props: { name: this.arrowIcons.end },
646
+ on: cache(this, 'onE', {
462
647
  mousedown: this.__scrollToEnd,
463
648
  touchstart: this.__scrollToEnd,
464
649
  mouseup: this.__stopAnimScroll,
@@ -52,6 +52,14 @@
52
52
  "category": "content|behavior"
53
53
  },
54
54
 
55
+ "active-class": {
56
+ "type": "String",
57
+ "desc": "The class to be set on the active tab",
58
+ "examples": [ "my-active-class" ],
59
+ "category": "style",
60
+ "addedIn": "v1.17"
61
+ },
62
+
55
63
  "active-color": {
56
64
  "extends": "color",
57
65
  "desc": "The color to be attributed to the text of the active tab",
@@ -127,14 +127,14 @@
127
127
  &--horizontal .q-tabs__arrow
128
128
  height: 100%
129
129
 
130
- &--left
130
+ &--start
131
131
  top: 0
132
- left: 0 #{"/* rtl:ignore */"}
132
+ left: 0
133
133
  bottom: 0
134
134
 
135
- &--right
135
+ &--end
136
136
  top: 0
137
- right: 0 #{"/* rtl:ignore */"}
137
+ right: 0
138
138
  bottom: 0
139
139
 
140
140
  &--vertical
@@ -150,12 +150,12 @@
150
150
  height: 36px
151
151
  text-align: center
152
152
 
153
- &--left
153
+ &--start
154
154
  top: 0
155
155
  left: 0
156
156
  right: 0
157
157
 
158
- &--right
158
+ &--end
159
159
  left: 0
160
160
  right: 0
161
161
  bottom: 0
@@ -127,14 +127,14 @@
127
127
  &--horizontal .q-tabs__arrow
128
128
  height: 100%
129
129
 
130
- &--left
130
+ &--start
131
131
  top: 0
132
- left: 0 /* rtl:ignore */
132
+ left: 0
133
133
  bottom: 0
134
134
 
135
- &--right
135
+ &--end
136
136
  top: 0
137
- right: 0 /* rtl:ignore */
137
+ right: 0
138
138
  bottom: 0
139
139
 
140
140
  &--vertical
@@ -150,12 +150,12 @@
150
150
  height: 36px
151
151
  text-align: center
152
152
 
153
- &--left
153
+ &--start
154
154
  top: 0
155
155
  left: 0
156
156
  right: 0
157
157
 
158
- &--right
158
+ &--end
159
159
  left: 0
160
160
  right: 0
161
161
  bottom: 0
@@ -286,10 +286,14 @@ export default Vue.extend({
286
286
 
287
287
  methods: {
288
288
  setNow () {
289
- this.__updateValue({
289
+ const date = {
290
290
  ...this.__getCurrentDate(),
291
291
  ...this.__getCurrentTime()
292
- })
292
+ }
293
+
294
+ this.__updateValue(date)
295
+ Object.assign(this.innerModel, date) // reset any pending changes to innerModel
296
+
293
297
  this.view = 'Hour'
294
298
  },
295
299
 
@@ -20,7 +20,7 @@
20
20
  &__subtitle
21
21
  font-size: 12px
22
22
  margin-bottom: 8px
23
- opacity: .4
23
+ opacity: .6
24
24
  text-transform: uppercase
25
25
  letter-spacing: 1px
26
26
  font-weight: 700
@@ -240,4 +240,3 @@
240
240
 
241
241
  &__subtitle, &__content
242
242
  width: 50%
243
-
@@ -20,7 +20,7 @@
20
20
  &__subtitle
21
21
  font-size: 12px
22
22
  margin-bottom: 8px
23
- opacity: .4
23
+ opacity: .6
24
24
  text-transform: uppercase
25
25
  letter-spacing: 1px
26
26
  font-weight: 700
@@ -240,4 +240,3 @@
240
240
 
241
241
  &__subtitle, &__content
242
242
  width: 50%
243
-
@@ -39,7 +39,7 @@
39
39
  "desc": "URL to the avatar image; Icon takes precedence if used, so it replaces avatar",
40
40
  "transformAssetUrls": true,
41
41
  "examples": [
42
- "(statics folder) src=\"statics/img/my-bg.png\"",
42
+ "(public folder) src=\"img/my-bg.png\"",
43
43
  "(assets folder) src=\"~assets/my-img.png\"",
44
44
  "(relative path format) :src=\"require('./my_img.jpg')\"",
45
45
  "(URL) src=\"https://placeimg.com/500/300/nature\""
@@ -10,6 +10,8 @@ import { stopAndPrevent } from '../../utils/event.js'
10
10
  import { shouldIgnoreKey } from '../../utils/key-composition.js'
11
11
  import cache from '../../utils/cache.js'
12
12
 
13
+ const tickStrategyOptions = [ 'none', 'strict', 'leaf', 'leaf-filtered' ]
14
+
13
15
  export default Vue.extend({
14
16
  name: 'QTree',
15
17
 
@@ -33,6 +35,8 @@ export default Vue.extend({
33
35
  default: 'children'
34
36
  },
35
37
 
38
+ dense: Boolean,
39
+
36
40
  color: String,
37
41
  controlColor: String,
38
42
  textColor: String,
@@ -43,7 +47,7 @@ export default Vue.extend({
43
47
  tickStrategy: {
44
48
  type: String,
45
49
  default: 'none',
46
- validator: v => ['none', 'strict', 'leaf', 'leaf-filtered'].includes(v)
50
+ validator: v => tickStrategyOptions.includes(v)
47
51
  },
48
52
  ticked: Array, // sync
49
53
  expanded: Array, // sync
@@ -71,8 +75,8 @@ export default Vue.extend({
71
75
 
72
76
  computed: {
73
77
  classes () {
74
- return `q-tree` +
75
- (this.noConnectors === true ? ` q-tree--no-connectors` : '') +
78
+ return `q-tree q-tree--${this.dense === true ? 'dense' : 'standard'}` +
79
+ (this.noConnectors === true ? ' q-tree--no-connectors' : '') +
76
80
  (this.isDark === true ? ` q-tree--dark` : '') +
77
81
  (this.color !== void 0 ? ` text-${this.color}` : '')
78
82
  },
@@ -514,13 +518,13 @@ export default Vue.extend({
514
518
 
515
519
  meta.lazy === 'loading'
516
520
  ? h(QSpinner, {
517
- staticClass: 'q-tree__spinner q-mr-xs',
521
+ staticClass: 'q-tree__spinner',
518
522
  props: { color: this.computedControlColor }
519
523
  })
520
524
  : (
521
525
  isParent === true
522
526
  ? h(QIcon, {
523
- staticClass: 'q-tree__arrow q-mr-xs',
527
+ staticClass: 'q-tree__arrow',
524
528
  class: { 'q-tree__arrow--rotate': meta.expanded },
525
529
  props: { name: this.computedIcon },
526
530
  on: {
@@ -534,7 +538,7 @@ export default Vue.extend({
534
538
 
535
539
  meta.hasTicking === true && meta.noTick !== true
536
540
  ? h(QCheckbox, {
537
- staticClass: 'q-mr-xs',
541
+ staticClass: 'q-tree__tickbox',
538
542
  props: {
539
543
  value: meta.indeterminate === true ? null : meta.ticked,
540
544
  color: this.computedControlColor,
@@ -63,6 +63,11 @@
63
63
  "desc": "Color name for selected nodes (from the Quasar Color Palette)"
64
64
  },
65
65
 
66
+ "dense": {
67
+ "extends": "dense",
68
+ "addedIn": "v1.17"
69
+ },
70
+
66
71
  "dark": {
67
72
  "extends": "dark"
68
73
  },