quasar 2.4.2 → 2.4.6

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 (180) hide show
  1. package/dist/api/BottomSheet.json +6 -2
  2. package/dist/api/LoadingBar.json +1 -1
  3. package/dist/api/Notify.json +25 -25
  4. package/dist/api/QAjaxBar.json +23 -4
  5. package/dist/api/QAvatar.json +1 -1
  6. package/dist/api/QBreadcrumbsEl.json +1 -1
  7. package/dist/api/QBtn.json +2 -2
  8. package/dist/api/QBtnDropdown.json +3 -3
  9. package/dist/api/QBtnToggle.json +1 -1
  10. package/dist/api/QCarousel.json +4 -4
  11. package/dist/api/QCarouselSlide.json +2 -2
  12. package/dist/api/QChatMessage.json +1 -1
  13. package/dist/api/QChip.json +4 -4
  14. package/dist/api/QExpansionItem.json +3 -3
  15. package/dist/api/QFab.json +2 -2
  16. package/dist/api/QFabAction.json +1 -1
  17. package/dist/api/QImg.json +2 -2
  18. package/dist/api/QLinearProgress.json +1 -1
  19. package/dist/api/QPagination.json +4 -4
  20. package/dist/api/QParallax.json +1 -1
  21. package/dist/api/QPullToRefresh.json +1 -1
  22. package/dist/api/QRadio.json +3 -1
  23. package/dist/api/QRating.json +3 -3
  24. package/dist/api/QRouteTab.json +1 -1
  25. package/dist/api/QSelect.json +2 -2
  26. package/dist/api/QStep.json +4 -4
  27. package/dist/api/QStepper.json +4 -4
  28. package/dist/api/QTab.json +1 -1
  29. package/dist/api/QTable.json +4 -4
  30. package/dist/api/QTimelineEntry.json +2 -2
  31. package/dist/api/QToggle.json +1 -1
  32. package/dist/api/QTree.json +1 -1
  33. package/dist/api/QVideo.json +11 -1
  34. package/dist/icon-set/bootstrap-icons.umd.prod.js +1 -1
  35. package/dist/icon-set/eva-icons.umd.prod.js +1 -1
  36. package/dist/icon-set/fontawesome-v5-pro.umd.prod.js +1 -1
  37. package/dist/icon-set/fontawesome-v5.umd.prod.js +1 -1
  38. package/dist/icon-set/ionicons-v4.umd.prod.js +1 -1
  39. package/dist/icon-set/line-awesome.umd.prod.js +1 -1
  40. package/dist/icon-set/material-icons-outlined.umd.prod.js +1 -1
  41. package/dist/icon-set/material-icons-round.umd.prod.js +1 -1
  42. package/dist/icon-set/material-icons-sharp.umd.prod.js +1 -1
  43. package/dist/icon-set/material-icons.umd.prod.js +1 -1
  44. package/dist/icon-set/mdi-v3.umd.prod.js +1 -1
  45. package/dist/icon-set/mdi-v4.umd.prod.js +1 -1
  46. package/dist/icon-set/mdi-v5.umd.prod.js +1 -1
  47. package/dist/icon-set/mdi-v6.umd.prod.js +1 -1
  48. package/dist/icon-set/svg-bootstrap-icons.umd.prod.js +1 -1
  49. package/dist/icon-set/svg-eva-icons.umd.prod.js +1 -1
  50. package/dist/icon-set/svg-fontawesome-v5.umd.prod.js +1 -1
  51. package/dist/icon-set/svg-ionicons-v4.umd.prod.js +1 -1
  52. package/dist/icon-set/svg-ionicons-v5.umd.prod.js +1 -1
  53. package/dist/icon-set/svg-ionicons-v6.umd.prod.js +1 -1
  54. package/dist/icon-set/svg-line-awesome.umd.prod.js +1 -1
  55. package/dist/icon-set/svg-material-icons-outlined.umd.prod.js +1 -1
  56. package/dist/icon-set/svg-material-icons-round.umd.prod.js +1 -1
  57. package/dist/icon-set/svg-material-icons-sharp.umd.prod.js +1 -1
  58. package/dist/icon-set/svg-material-icons.umd.prod.js +1 -1
  59. package/dist/icon-set/svg-mdi-v4.umd.prod.js +1 -1
  60. package/dist/icon-set/svg-mdi-v5.umd.prod.js +1 -1
  61. package/dist/icon-set/svg-mdi-v6.umd.prod.js +1 -1
  62. package/dist/icon-set/svg-themify.umd.prod.js +1 -1
  63. package/dist/icon-set/themify.umd.prod.js +1 -1
  64. package/dist/lang/ar.umd.prod.js +1 -1
  65. package/dist/lang/az-Latn.umd.prod.js +1 -1
  66. package/dist/lang/bg.umd.prod.js +1 -1
  67. package/dist/lang/bn.umd.prod.js +1 -1
  68. package/dist/lang/ca.umd.prod.js +1 -1
  69. package/dist/lang/cs.umd.prod.js +1 -1
  70. package/dist/lang/da.umd.prod.js +1 -1
  71. package/dist/lang/de.umd.prod.js +1 -1
  72. package/dist/lang/el.umd.prod.js +1 -1
  73. package/dist/lang/en-GB.umd.prod.js +1 -1
  74. package/dist/lang/en-US.umd.prod.js +1 -1
  75. package/dist/lang/eo.umd.prod.js +1 -1
  76. package/dist/lang/es.umd.prod.js +1 -1
  77. package/dist/lang/et.umd.prod.js +1 -1
  78. package/dist/lang/fa-IR.umd.prod.js +1 -1
  79. package/dist/lang/fa.umd.prod.js +1 -1
  80. package/dist/lang/fi.umd.prod.js +1 -1
  81. package/dist/lang/fr.umd.prod.js +1 -1
  82. package/dist/lang/gn.umd.prod.js +1 -1
  83. package/dist/lang/he.umd.prod.js +1 -1
  84. package/dist/lang/hr.umd.prod.js +1 -1
  85. package/dist/lang/hu.umd.prod.js +1 -1
  86. package/dist/lang/id.umd.prod.js +1 -1
  87. package/dist/lang/is.umd.prod.js +1 -1
  88. package/dist/lang/it.umd.prod.js +1 -1
  89. package/dist/lang/ja.umd.prod.js +1 -1
  90. package/dist/lang/km.umd.prod.js +1 -1
  91. package/dist/lang/ko-KR.umd.prod.js +1 -1
  92. package/dist/lang/kur-CKB.umd.prod.js +1 -1
  93. package/dist/lang/lt.umd.prod.js +1 -1
  94. package/dist/lang/lu.umd.prod.js +1 -1
  95. package/dist/lang/lv.umd.prod.js +1 -1
  96. package/dist/lang/ml.umd.prod.js +1 -1
  97. package/dist/lang/ms.umd.prod.js +1 -1
  98. package/dist/lang/nb-NO.umd.prod.js +1 -1
  99. package/dist/lang/nl.umd.prod.js +1 -1
  100. package/dist/lang/pl.umd.prod.js +1 -1
  101. package/dist/lang/pt-BR.umd.prod.js +1 -1
  102. package/dist/lang/pt.umd.prod.js +1 -1
  103. package/dist/lang/ro.umd.prod.js +1 -1
  104. package/dist/lang/ru.umd.prod.js +1 -1
  105. package/dist/lang/sk.umd.prod.js +1 -1
  106. package/dist/lang/sl.umd.prod.js +1 -1
  107. package/dist/lang/sr-CYR.umd.prod.js +1 -1
  108. package/dist/lang/sr.umd.prod.js +1 -1
  109. package/dist/lang/sv.umd.prod.js +1 -1
  110. package/dist/lang/ta.umd.prod.js +1 -1
  111. package/dist/lang/th.umd.prod.js +1 -1
  112. package/dist/lang/tr.umd.prod.js +1 -1
  113. package/dist/lang/ug.umd.prod.js +1 -1
  114. package/dist/lang/uk.umd.prod.js +1 -1
  115. package/dist/lang/vi.umd.prod.js +1 -1
  116. package/dist/lang/zh-CN.umd.prod.js +1 -1
  117. package/dist/lang/zh-TW.umd.prod.js +1 -1
  118. package/dist/quasar.cjs.prod.js +2 -2
  119. package/dist/quasar.css +7 -6
  120. package/dist/quasar.esm.prod.js +2 -2
  121. package/dist/quasar.prod.css +1 -1
  122. package/dist/quasar.rtl.css +7 -6
  123. package/dist/quasar.rtl.prod.css +1 -1
  124. package/dist/quasar.sass +7 -7
  125. package/dist/quasar.umd.js +420 -284
  126. package/dist/quasar.umd.prod.js +2 -2
  127. package/dist/ssr-directives/Morph.js +1 -1
  128. package/dist/types/index.d.ts +29 -11
  129. package/dist/types/utils/date.d.ts +2 -1
  130. package/dist/vetur/quasar-attributes.json +13 -5
  131. package/dist/vetur/quasar-tags.json +4 -2
  132. package/dist/web-types/web-types.json +80 -62
  133. package/package.json +1 -1
  134. package/src/api.extends.json +1 -1
  135. package/src/components/ajax-bar/QAjaxBar.js +47 -26
  136. package/src/components/ajax-bar/QAjaxBar.json +22 -4
  137. package/src/components/breadcrumbs/QBreadcrumbs.js +3 -3
  138. package/src/components/breadcrumbs/QBreadcrumbsEl.js +2 -2
  139. package/src/components/btn/use-btn.js +4 -1
  140. package/src/components/btn-toggle/QBtnToggle.js +2 -0
  141. package/src/components/carousel/QCarouselSlide.json +2 -2
  142. package/src/components/chat/QChatMessage.json +1 -1
  143. package/src/components/dialog/QDialog.js +7 -5
  144. package/src/components/icon/QIcon.js +36 -32
  145. package/src/components/icon/QIcon.sass +0 -1
  146. package/src/components/img/QImg.json +2 -2
  147. package/src/components/layout/QLayout.js +49 -1
  148. package/src/components/linear-progress/QLinearProgress.json +1 -1
  149. package/src/components/menu/QMenu.js +6 -2
  150. package/src/components/pagination/QPagination.js +4 -4
  151. package/src/components/parallax/QParallax.json +1 -1
  152. package/src/components/radio/QRadio.js +2 -6
  153. package/src/components/radio/QRadio.json +1 -1
  154. package/src/components/range/QRange.js +67 -89
  155. package/src/components/rating/QRating.json +3 -3
  156. package/src/components/resize-observer/QResizeObserver.js +11 -10
  157. package/src/components/scroll-area/QScrollArea.js +5 -1
  158. package/src/components/scroll-area/QScrollArea.sass +1 -0
  159. package/src/components/scroll-observer/QScrollObserver.js +2 -0
  160. package/src/components/select/QSelect.json +1 -1
  161. package/src/components/slider/QSlider.js +20 -10
  162. package/src/components/slider/QSlider.sass +5 -6
  163. package/src/components/slider/use-slider.js +19 -16
  164. package/src/components/tabs/QTabs.js +27 -11
  165. package/src/components/timeline/QTimeline.sass +1 -2
  166. package/src/components/timeline/QTimelineEntry.json +1 -1
  167. package/src/components/tooltip/QTooltip.js +1 -2
  168. package/src/components/video/QVideo.js +4 -1
  169. package/src/components/video/QVideo.json +12 -1
  170. package/src/composables/private/use-field.js +13 -15
  171. package/src/composables/private/use-model-toggle.js +1 -1
  172. package/src/composables/private/use-portal.js +9 -7
  173. package/src/composables/private/use-tick.js +7 -14
  174. package/src/css/core/visibility.sass +0 -1
  175. package/src/plugins/BottomSheet.json +7 -1
  176. package/src/plugins/LoadingBar.json +1 -1
  177. package/src/plugins/Notify.json +22 -22
  178. package/src/utils/clone.js +53 -4
  179. package/src/utils/private/focus-manager.js +8 -10
  180. package/src/utils/private/global-dialog.js +4 -4
@@ -5,22 +5,22 @@ import { between } from '../../utils/format.js'
5
5
 
6
6
  const
7
7
  xhr = __QUASAR_SSR_SERVER__ ? null : XMLHttpRequest,
8
- send = __QUASAR_SSR_SERVER__ ? null : xhr.prototype.send,
9
- stackStart = [],
10
- stackStop = []
8
+ open = __QUASAR_SSR_SERVER__ ? null : xhr.prototype.open,
9
+ positionValues = [ 'top', 'right', 'bottom', 'left' ]
11
10
 
11
+ let stack = []
12
12
  let highjackCount = 0
13
13
 
14
14
  function translate ({ p, pos, active, horiz, reverse, dir }) {
15
15
  let x = 1, y = 1
16
16
 
17
- if (horiz) {
18
- if (reverse) { x = -1 }
17
+ if (horiz === true) {
18
+ if (reverse === true) { x = -1 }
19
19
  if (pos === 'bottom') { y = -1 }
20
20
  return { transform: `translate3d(${ x * (p - 100) }%,${ active ? 0 : y * -200 }%,0)` }
21
21
  }
22
22
 
23
- if (reverse) { y = -1 }
23
+ if (reverse === true) { y = -1 }
24
24
  if (pos === 'right') { x = -1 }
25
25
  return { transform: `translate3d(${ active ? 0 : dir * x * -200 }%,${ y * (p - 100) }%,0)` }
26
26
  }
@@ -46,32 +46,45 @@ function inc (p, amount) {
46
46
  return between(p + amount, 0, 100)
47
47
  }
48
48
 
49
- function highjackAjax (start, stop) {
50
- stackStart.push(start)
51
- stackStop.push(stop)
52
-
49
+ function highjackAjax (stackEntry) {
53
50
  highjackCount++
54
51
 
52
+ stack.push(stackEntry)
53
+
55
54
  if (highjackCount > 1) { return }
56
55
 
57
- function endHandler () {
58
- stackStop.forEach(fn => { fn() })
59
- }
56
+ xhr.prototype.open = function (_, url) {
57
+ const stopStack = []
58
+
59
+ const loadStart = () => {
60
+ stack.forEach(entry => {
61
+ if (
62
+ entry.hijackFilter.value === null
63
+ || (entry.hijackFilter.value(url) === true)
64
+ ) {
65
+ entry.start()
66
+ stopStack.push(entry.stop)
67
+ }
68
+ })
69
+ }
60
70
 
61
- xhr.prototype.send = function (/* ...args */) {
62
- stackStart.forEach(fn => { fn() })
63
- this.addEventListener('loadend', endHandler, false)
64
- send.apply(this, arguments)
71
+ const loadEnd = () => {
72
+ stopStack.forEach(stop => { stop() })
73
+ }
74
+
75
+ this.addEventListener('loadstart', loadStart, { once: true })
76
+ this.addEventListener('loadend', loadEnd, { once: true })
77
+
78
+ open.apply(this, arguments)
65
79
  }
66
80
  }
67
81
 
68
- function restoreAjax (start, stop) {
69
- stackStart.splice(stackStart.indexOf(start), 1)
70
- stackStop.splice(stackStop.indexOf(stop), 1)
82
+ function restoreAjax (start) {
83
+ stack = stack.filter(entry => entry.start !== start)
71
84
 
72
85
  highjackCount = Math.max(0, highjackCount - 1)
73
86
  if (highjackCount === 0) {
74
- xhr.prototype.send = send
87
+ xhr.prototype.open = open
75
88
  }
76
89
  }
77
90
 
@@ -82,15 +95,19 @@ export default createComponent({
82
95
  position: {
83
96
  type: String,
84
97
  default: 'top',
85
- validator: val => [ 'top', 'right', 'bottom', 'left' ].includes(val)
98
+ validator: val => positionValues.includes(val)
86
99
  },
100
+
87
101
  size: {
88
102
  type: String,
89
103
  default: '2px'
90
104
  },
105
+
91
106
  color: String,
92
107
  skipHijack: Boolean,
93
- reverse: Boolean
108
+ reverse: Boolean,
109
+
110
+ hijackFilter: Function
94
111
  },
95
112
 
96
113
  emits: [ 'start', 'stop' ],
@@ -122,7 +139,7 @@ export default createComponent({
122
139
  active,
123
140
  horiz: horizontal.value,
124
141
  reverse: proxy.$q.lang.rtl === true && [ 'top', 'bottom' ].includes(props.position)
125
- ? !props.reverse
142
+ ? props.reverse === false
126
143
  : props.reverse,
127
144
  dir: proxy.$q.lang.rtl === true ? -1 : 1
128
145
  })
@@ -218,13 +235,17 @@ export default createComponent({
218
235
  onMounted(() => {
219
236
  if (props.skipHijack !== true) {
220
237
  hijacked = true
221
- highjackAjax(start, stop)
238
+ highjackAjax({
239
+ start,
240
+ stop,
241
+ hijackFilter: computed(() => props.hijackFilter || null)
242
+ })
222
243
  }
223
244
  })
224
245
 
225
246
  onBeforeUnmount(() => {
226
247
  clearTimeout(timer)
227
- hijacked === true && restoreAjax(start, stop)
248
+ hijacked === true && restoreAjax(start)
228
249
  })
229
250
 
230
251
  // expose public methods
@@ -22,16 +22,34 @@
22
22
  "extends": "color"
23
23
  },
24
24
 
25
- "skip-hijack": {
25
+ "reverse": {
26
26
  "type": "Boolean",
27
- "desc": "Skip Ajax hijacking (not a reactive prop)",
27
+ "desc": "Reverse direction of progress",
28
28
  "category": "behavior"
29
29
  },
30
30
 
31
- "reverse": {
31
+ "skip-hijack": {
32
32
  "type": "Boolean",
33
- "desc": "Reverse direction of progress",
33
+ "desc": "Skip Ajax hijacking (not a reactive prop)",
34
34
  "category": "behavior"
35
+ },
36
+
37
+ "hijack-filter": {
38
+ "type": "Function",
39
+ "desc": "Filter which URL should trigger start() + stop()",
40
+ "params": {
41
+ "url": {
42
+ "type": "String",
43
+ "desc": "The URL being triggered",
44
+ "examples": [ "https://some.url/path" ]
45
+ }
46
+ },
47
+ "returns": {
48
+ "type": "Boolean",
49
+ "desc": "Should the URL received as param trigger start() + stop()?"
50
+ },
51
+ "category": "behavior",
52
+ "addedIn": "v2.4.5"
35
53
  }
36
54
  },
37
55
 
@@ -40,7 +40,7 @@ export default createComponent({
40
40
  )
41
41
 
42
42
  const sepClass = computed(() => (props.separatorColor ? ` text-${ props.separatorColor }` : ''))
43
- const activeClass = computed(() => `text-${ props.activeColor }`)
43
+ const activeClass = computed(() => ` text-${ props.activeColor }`)
44
44
 
45
45
  return () => {
46
46
  const vnodes = getNormalizedVNodes(
@@ -62,8 +62,8 @@ export default createComponent({
62
62
  if (comp.type !== void 0 && comp.type.name === 'QBreadcrumbsEl') {
63
63
  const middle = els < len
64
64
  const disabled = comp.props !== null && disabledValues.includes(comp.props.disable)
65
- const cls = (middle === true ? ' q-breadcrumbs--last' : '')
66
- + (disabled !== true && middle === true ? ' ' + activeClass.value : '')
65
+ const cls = (middle === true ? '' : ' q-breadcrumbs--last')
66
+ + (disabled !== true && middle === true ? activeClass.value : '')
67
67
 
68
68
  els++
69
69
 
@@ -22,13 +22,13 @@ export default createComponent({
22
22
  },
23
23
 
24
24
  setup (props, { slots }) {
25
- const { linkTag, linkProps, hasRouterLink, navigateToRouterLink } = useRouterLink()
25
+ const { linkTag, linkProps, linkClass, hasRouterLink, navigateToRouterLink } = useRouterLink()
26
26
 
27
27
  const data = computed(() => {
28
28
  const acc = {
29
29
  class: 'q-breadcrumbs__el q-link '
30
30
  + 'flex inline items-center relative-position '
31
- + (props.disable !== true ? 'q-link--focusable' : 'q-breadcrumbs__el--disable'),
31
+ + (props.disable !== true ? 'q-link--focusable' + linkClass.value : 'q-breadcrumbs__el--disable'),
32
32
  ...linkProps.value
33
33
  }
34
34
  if (hasRouterLink.value === true) {
@@ -129,7 +129,10 @@ export default function (props) {
129
129
  }
130
130
 
131
131
  if (linkTag.value === 'a') {
132
- if (acc.href === void 0) {
132
+ if (props.disable === true) {
133
+ acc[ 'aria-disabled' ] = 'true'
134
+ }
135
+ else if (acc.href === void 0) {
133
136
  acc.role = 'button'
134
137
  }
135
138
  if (hasRouterLink.value !== true && mediaTypeRE.test(props.type) === true) {
@@ -89,6 +89,8 @@ export default createComponent({
89
89
  key: i,
90
90
  onClick (e) { set(value, item, e) },
91
91
 
92
+ 'aria-pressed': value === props.modelValue ? 'true' : 'false',
93
+
92
94
  ...attrs,
93
95
  ...opt,
94
96
 
@@ -16,10 +16,10 @@
16
16
 
17
17
  "img-src": {
18
18
  "type": "String",
19
- "desc": "URL pointing to a slide background image (use statics folder)",
19
+ "desc": "URL pointing to a slide background image (use public folder)",
20
20
  "transformAssetUrls": true,
21
21
  "examples": [
22
- "(statics folder) src=\"statics/img/my-bg.png\"",
22
+ "(public folder) src=\"img/my-bg.png\"",
23
23
  "(assets folder) src=\"~assets/my-img.png\"",
24
24
  "(relative path format) :src=\"require('./my_img.jpg')\"",
25
25
  "(URL) src=\"https://placeimg.com/500/300/nature\""
@@ -41,7 +41,7 @@
41
41
  "desc": "URL to the avatar image of the author",
42
42
  "transformAssetUrls": true,
43
43
  "examples": [
44
- "(statics folder) src=\"statics/boy-avatar.png\"",
44
+ "(public folder) src=\"boy-avatar.png\"",
45
45
  "(assets folder) src=\"~assets/boy-avatar.png\"",
46
46
  "(relative path format) :src=\"require('./my_img.jpg')\"",
47
47
  "(URL) src=\"https://placeimg.com/500/300/nature\""
@@ -94,7 +94,7 @@ export default createComponent({
94
94
 
95
95
  const { preventBodyScroll } = usePreventScroll()
96
96
  const { registerTimeout, removeTimeout } = useTimeout()
97
- const { registerTick, removeTick, prepareTick } = useTick()
97
+ const { registerTick, removeTick } = useTick()
98
98
 
99
99
  const { showPortal, hidePortal, portalIsActive, renderPortal } = usePortal(
100
100
  vm, innerRef, renderPortalContent, /* pls do check if on a global dialog */ true
@@ -193,7 +193,6 @@ export default createComponent({
193
193
  if (props.noFocus !== true) {
194
194
  document.activeElement !== null && document.activeElement.blur()
195
195
  registerTick(focus)
196
- prepareTick()
197
196
  }
198
197
 
199
198
  registerTimeout(() => {
@@ -239,6 +238,7 @@ export default createComponent({
239
238
 
240
239
  if (refocusTarget !== null) {
241
240
  refocusTarget.focus()
241
+ refocusTarget = null
242
242
  }
243
243
 
244
244
  registerTimeout(() => {
@@ -306,6 +306,10 @@ export default createComponent({
306
306
  removeEscapeKey(onEscapeKey)
307
307
  }
308
308
  }
309
+
310
+ if (hiding !== true) {
311
+ refocusTarget = null
312
+ }
309
313
  }
310
314
 
311
315
  function updateMaximized (active) {
@@ -364,9 +368,7 @@ export default createComponent({
364
368
  }
365
369
  })
366
370
 
367
- onBeforeUnmount(() => {
368
- cleanup()
369
- })
371
+ onBeforeUnmount(cleanup)
370
372
 
371
373
  function renderPortalContent () {
372
374
  return h('div', {
@@ -5,6 +5,8 @@ import useSize, { useSizeProps } from '../../composables/private/use-size.js'
5
5
  import { createComponent } from '../../utils/private/create.js'
6
6
  import { hSlot, hMergeSlot } from '../../utils/private/render.js'
7
7
 
8
+ const defaultViewBox = '0 0 24 24'
9
+
8
10
  const sameFn = i => i
9
11
  const ionFn = i => `ionicons ${ i }`
10
12
 
@@ -58,7 +60,7 @@ export default createComponent({
58
60
 
59
61
  const classes = computed(() =>
60
62
  'q-icon'
61
- + (props.left === true ? ' on-left' : '')
63
+ + (props.left === true ? ' on-left' : '') // TODO Qv3: drop this
62
64
  + (props.right === true ? ' on-right' : '')
63
65
  + (props.color !== void 0 ? ` text-${ props.color }` : '')
64
66
  )
@@ -68,10 +70,7 @@ export default createComponent({
68
70
  let icon = props.name
69
71
 
70
72
  if (!icon) {
71
- return {
72
- none: true,
73
- cls: classes.value
74
- }
73
+ return { none: true }
75
74
  }
76
75
 
77
76
  if ($q.iconMapFn !== null) {
@@ -82,7 +81,7 @@ export default createComponent({
82
81
  }
83
82
  else {
84
83
  return {
85
- cls: res.cls + ' ' + classes.value,
84
+ cls: res.cls,
86
85
  content: res.content !== void 0
87
86
  ? res.content
88
87
  : ' '
@@ -92,39 +91,32 @@ export default createComponent({
92
91
  }
93
92
 
94
93
  if (mRE.test(icon) === true) {
95
- const [ def, viewBox ] = icon.split('|')
94
+ const [ def, viewBox = defaultViewBox ] = icon.split('|')
96
95
 
97
96
  return {
98
97
  svg: true,
99
- cls: classes.value,
98
+ viewBox,
100
99
  nodes: def.split('&&').map(path => {
101
100
  const [ d, style, transform ] = path.split('@@')
102
- return h('path', {
103
- style,
104
- d,
105
- transform
106
- })
107
- }),
108
- viewBox: viewBox !== void 0 ? viewBox : '0 0 24 24'
101
+ return h('path', { style, d, transform })
102
+ })
109
103
  }
110
104
  }
111
105
 
112
106
  if (imgRE.test(icon) === true) {
113
107
  return {
114
108
  img: true,
115
- cls: classes.value,
116
109
  src: icon.substring(4)
117
110
  }
118
111
  }
119
112
 
120
113
  if (svgUseRE.test(icon) === true) {
121
- const [ def, viewBox ] = icon.split('|')
114
+ const [ def, viewBox = defaultViewBox ] = icon.split('|')
122
115
 
123
116
  return {
124
117
  svguse: true,
125
- cls: classes.value,
126
118
  src: def.substring(7),
127
- viewBox: viewBox !== void 0 ? viewBox : '0 0 24 24'
119
+ viewBox
128
120
  }
129
121
  }
130
122
 
@@ -158,14 +150,14 @@ export default createComponent({
158
150
  }
159
151
 
160
152
  return {
161
- cls: cls + ' ' + classes.value,
153
+ cls,
162
154
  content
163
155
  }
164
156
  })
165
157
 
166
158
  return () => {
167
159
  const data = {
168
- class: type.value.cls,
160
+ class: classes.value,
169
161
  style: sizeStyle.value,
170
162
  'aria-hidden': 'true',
171
163
  role: 'presentation'
@@ -176,24 +168,36 @@ export default createComponent({
176
168
  }
177
169
 
178
170
  if (type.value.img === true) {
179
- data.src = type.value.src
180
- return h('img', data)
171
+ return h('div', data, hMergeSlot(slots.default, [
172
+ h('img', {
173
+ class: type.value.cls,
174
+ src: type.value.src
175
+ })
176
+ ]))
181
177
  }
182
178
 
183
179
  if (type.value.svg === true) {
184
- data.viewBox = type.value.viewBox
185
-
186
- return h('svg', data, hMergeSlot(slots.default, type.value.nodes))
180
+ return h('div', data, hMergeSlot(slots.default, [
181
+ h('svg', {
182
+ class: type.value.cls,
183
+ viewBox: type.value.viewBox
184
+ }, type.value.nodes)
185
+ ]))
187
186
  }
188
187
 
189
188
  if (type.value.svguse === true) {
190
- data.viewBox = type.value.viewBox
189
+ return h('div', data, hMergeSlot(slots.default, [
190
+ h('svg', {
191
+ class: type.value.cls,
192
+ viewBox: type.value.viewBox
193
+ }, [
194
+ h('use', { 'xlink:href': type.value.src })
195
+ ])
196
+ ]))
197
+ }
191
198
 
192
- return h(
193
- 'svg',
194
- data,
195
- hMergeSlot(slots.default, [ h('use', { 'xlink:href': type.value.src }) ])
196
- )
199
+ if (type.value.cls !== void 0) {
200
+ data.class += ' ' + type.value.cls
197
201
  }
198
202
 
199
203
  return h(props.tag, data, hMergeSlot(slots.default, [
@@ -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
@@ -11,7 +11,7 @@
11
11
  "desc": "Path to image",
12
12
  "transformAssetUrls": true,
13
13
  "examples": [
14
- "(statics folder) src=\"statics/img/something.png\"",
14
+ "(public folder) src=\"img/something.png\"",
15
15
  "(assets folder) src=\"~assets/my-img.gif\"",
16
16
  "(relative path format) :src=\"require('./my_img.jpg')\"",
17
17
  "(URL) src=\"https://placeimg.com/500/300/nature\""
@@ -44,7 +44,7 @@
44
44
  "desc": "While waiting for your image to load, you can use a placeholder image",
45
45
  "transformAssetUrls": true,
46
46
  "examples": [
47
- "(statics folder) src=\"statics/img/some-placeholder.png\"",
47
+ "(public folder) src=\"img/some-placeholder.png\"",
48
48
  "(assets folder) src=\"~assets/my-placeholder.gif\"",
49
49
  "(relative path format) :src=\"require('./placeholder.jpg')\"",
50
50
  "(URL) src=\"https://placeimg.com/500/300/nature\""
@@ -1,4 +1,4 @@
1
- import { h, ref, reactive, computed, provide, getCurrentInstance } from 'vue'
1
+ import { h, ref, reactive, computed, watch, provide, onUnmounted, getCurrentInstance } from 'vue'
2
2
 
3
3
  import { isRuntimeSsrPreHydration } from '../../plugins/Platform.js'
4
4
 
@@ -173,6 +173,54 @@ export default createComponent({
173
173
 
174
174
  provide(layoutKey, $layout)
175
175
 
176
+ // prevent scrollbar flicker while resizing window height
177
+ // if no page scrollbar is already present
178
+ if (__QUASAR_SSR__ !== true) {
179
+ let timer = null
180
+ const el = document.body
181
+
182
+ function restoreScrollbar () {
183
+ timer = null
184
+ el.classList.remove('hide-scrollbar')
185
+ }
186
+
187
+ function hideScrollbar () {
188
+ if (timer === null) {
189
+ // if it has no scrollbar then there's nothing to do
190
+
191
+ if (el.scrollHeight > window.innerHeight) {
192
+ return
193
+ }
194
+
195
+ el.classList.add('hide-scrollbar')
196
+ }
197
+ else {
198
+ clearTimeout(timer)
199
+ }
200
+
201
+ timer = setTimeout(restoreScrollbar, 300)
202
+ }
203
+
204
+ function updateScrollEvent (action) {
205
+ if (timer !== null && action === 'remove') {
206
+ clearTimeout(timer)
207
+ restoreScrollbar()
208
+ }
209
+
210
+ window[ `${ action }EventListener` ]('resize', hideScrollbar)
211
+ }
212
+
213
+ watch(
214
+ () => (props.container !== true && scrollbarWidth.value > 0 ? 'add' : 'remove'),
215
+ updateScrollEvent,
216
+ { immediate: true }
217
+ )
218
+
219
+ onUnmounted(() => {
220
+ updateScrollEvent('remove')
221
+ })
222
+ }
223
+
176
224
  return () => {
177
225
  const content = hMergeSlot(slots.default, [
178
226
  h(QScrollObserver, { onScroll: onPageScroll }),
@@ -70,7 +70,7 @@
70
70
 
71
71
  "animation-speed": {
72
72
  "extends": "animation-speed",
73
- "default": 300,
73
+ "default": 2100,
74
74
  "addedIn": "v2.3"
75
75
  }
76
76
  },
@@ -98,7 +98,7 @@ export default createComponent({
98
98
  )
99
99
 
100
100
  const isDark = useDark(props, $q)
101
- const { registerTick, removeTick, prepareTick } = useTick()
101
+ const { registerTick, removeTick } = useTick()
102
102
  const { registerTimeout, removeTimeout } = useTimeout()
103
103
  const { transition, transitionStyle } = useTransition(props, showing)
104
104
  const { localScrollTarget, changeScrollEvent, unconfigureScrollTarget } = useScrollTarget(props, configureScrollTarget)
@@ -225,7 +225,6 @@ export default createComponent({
225
225
  updatePosition()
226
226
  props.noFocus !== true && focus()
227
227
  })
228
- prepareTick()
229
228
 
230
229
  registerTimeout(() => {
231
230
  // required in order to avoid the "double-tap needed" issue
@@ -258,6 +257,7 @@ export default createComponent({
258
257
  )
259
258
  ) {
260
259
  refocusTarget.focus()
260
+ refocusTarget = null
261
261
  }
262
262
 
263
263
  registerTimeout(() => {
@@ -280,6 +280,10 @@ export default createComponent({
280
280
  removeClickOutside(clickOutsideProps)
281
281
  removeEscapeKey(onEscapeKey)
282
282
  }
283
+
284
+ if (hiding !== true) {
285
+ refocusTarget = null
286
+ }
283
287
  }
284
288
 
285
289
  function configureScrollTarget () {
@@ -309,8 +309,8 @@ export default createComponent({
309
309
  style,
310
310
  disable: props.disable,
311
311
  flat: !active,
312
- textColor: active ? props.textColor : void 0,
313
- label: props.min
312
+ label: props.min,
313
+ ...(active ? activeBtnProps.value : {})
314
314
  }, props.min))
315
315
  }
316
316
  if (boundaryEnd) {
@@ -320,8 +320,8 @@ export default createComponent({
320
320
  style,
321
321
  disable: props.disable,
322
322
  flat: !active,
323
- textColor: active ? props.textColor : void 0,
324
- label: props.max
323
+ label: props.max,
324
+ ...(active ? activeBtnProps.value : {})
325
325
  }, props.max))
326
326
  }
327
327
  if (ellipsesStart) {
@@ -9,7 +9,7 @@
9
9
  "desc": "Path to image (unless a 'media' slot is used)",
10
10
  "transformAssetUrls": true,
11
11
  "examples": [
12
- "(statics folder) src=\"statics/img/something.png\"",
12
+ "(public folder) src=\"img/something.png\"",
13
13
  "(assets folder) src=\"~assets/my-img.png\"",
14
14
  "(relative path format) :src=\"require('./my_img.jpg')\"",
15
15
  "(URL) src=\"https://some-site.net/some-img.jpg\""
@@ -33,12 +33,8 @@ export default createComponent({
33
33
  ...useSizeProps,
34
34
  ...useFormProps,
35
35
 
36
- modelValue: {
37
- required: true
38
- },
39
- val: {
40
- required: true
41
- },
36
+ modelValue: { required: true },
37
+ val: { required: true },
42
38
 
43
39
  label: String,
44
40
  leftLabel: Boolean,
@@ -13,7 +13,7 @@
13
13
  },
14
14
 
15
15
  "val": {
16
- "type": [ "Number", "String" ],
16
+ "type": [ "Number", "String", "null", "undefined" ],
17
17
  "required": true,
18
18
  "desc": "The actual value of the option with which model value is changed",
19
19
  "examples": [ "opt1", 50 ],