quasar 2.1.4 → 2.1.8

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 (131) hide show
  1. package/dist/api/Loading.json +5 -2
  2. package/dist/api/QColor.json +9 -2
  3. package/dist/api/QDate.json +5 -2
  4. package/dist/api/QFile.json +3 -1
  5. package/dist/api/QImg.json +15 -0
  6. package/dist/api/QInput.json +5 -2
  7. package/dist/api/QRadio.json +3 -1
  8. package/dist/api/QRange.json +13 -3
  9. package/dist/api/QSelect.json +3 -1
  10. package/dist/api/QSlider.json +9 -2
  11. package/dist/api/QTabs.json +3 -1
  12. package/dist/api/QTime.json +9 -2
  13. package/dist/icon-set/bootstrap-icons.umd.prod.js +1 -1
  14. package/dist/icon-set/eva-icons.umd.prod.js +1 -1
  15. package/dist/icon-set/fontawesome-v5-pro.umd.prod.js +1 -1
  16. package/dist/icon-set/fontawesome-v5.umd.prod.js +1 -1
  17. package/dist/icon-set/ionicons-v4.umd.prod.js +1 -1
  18. package/dist/icon-set/line-awesome.umd.prod.js +1 -1
  19. package/dist/icon-set/material-icons-outlined.umd.prod.js +1 -1
  20. package/dist/icon-set/material-icons-round.umd.prod.js +1 -1
  21. package/dist/icon-set/material-icons-sharp.umd.prod.js +1 -1
  22. package/dist/icon-set/material-icons.umd.prod.js +1 -1
  23. package/dist/icon-set/mdi-v3.umd.prod.js +1 -1
  24. package/dist/icon-set/mdi-v4.umd.prod.js +1 -1
  25. package/dist/icon-set/mdi-v5.umd.prod.js +1 -1
  26. package/dist/icon-set/mdi-v6.umd.prod.js +1 -1
  27. package/dist/icon-set/svg-bootstrap-icons.umd.prod.js +1 -1
  28. package/dist/icon-set/svg-eva-icons.umd.prod.js +1 -1
  29. package/dist/icon-set/svg-fontawesome-v5.umd.prod.js +1 -1
  30. package/dist/icon-set/svg-ionicons-v4.umd.prod.js +1 -1
  31. package/dist/icon-set/svg-ionicons-v5.umd.prod.js +1 -1
  32. package/dist/icon-set/svg-line-awesome.umd.prod.js +1 -1
  33. package/dist/icon-set/svg-material-icons-outlined.umd.prod.js +1 -1
  34. package/dist/icon-set/svg-material-icons-round.umd.prod.js +1 -1
  35. package/dist/icon-set/svg-material-icons-sharp.umd.prod.js +1 -1
  36. package/dist/icon-set/svg-material-icons.umd.prod.js +1 -1
  37. package/dist/icon-set/svg-mdi-v4.umd.prod.js +1 -1
  38. package/dist/icon-set/svg-mdi-v5.umd.prod.js +1 -1
  39. package/dist/icon-set/svg-mdi-v6.umd.prod.js +1 -1
  40. package/dist/icon-set/svg-themify.umd.prod.js +1 -1
  41. package/dist/icon-set/themify.umd.prod.js +1 -1
  42. package/dist/lang/ar.umd.prod.js +1 -1
  43. package/dist/lang/az-Latn.umd.prod.js +1 -1
  44. package/dist/lang/bg.umd.prod.js +1 -1
  45. package/dist/lang/bn.umd.prod.js +1 -1
  46. package/dist/lang/ca.umd.prod.js +1 -1
  47. package/dist/lang/cs.umd.prod.js +1 -1
  48. package/dist/lang/da.umd.prod.js +1 -1
  49. package/dist/lang/de.umd.prod.js +1 -1
  50. package/dist/lang/el.umd.prod.js +1 -1
  51. package/dist/lang/en-GB.umd.prod.js +1 -1
  52. package/dist/lang/en-US.umd.prod.js +1 -1
  53. package/dist/lang/eo.umd.prod.js +1 -1
  54. package/dist/lang/es.umd.prod.js +1 -1
  55. package/dist/lang/et.umd.prod.js +1 -1
  56. package/dist/lang/fa-IR.umd.prod.js +1 -1
  57. package/dist/lang/fa.umd.prod.js +1 -1
  58. package/dist/lang/fi.umd.prod.js +1 -1
  59. package/dist/lang/fr.umd.prod.js +1 -1
  60. package/dist/lang/gn.umd.prod.js +1 -1
  61. package/dist/lang/he.umd.prod.js +1 -1
  62. package/dist/lang/hr.umd.prod.js +1 -1
  63. package/dist/lang/hu.umd.prod.js +1 -1
  64. package/dist/lang/id.umd.prod.js +1 -1
  65. package/dist/lang/is.umd.prod.js +1 -1
  66. package/dist/lang/it.umd.prod.js +1 -1
  67. package/dist/lang/ja.umd.prod.js +1 -1
  68. package/dist/lang/km.umd.prod.js +1 -1
  69. package/dist/lang/ko-KR.umd.prod.js +1 -1
  70. package/dist/lang/kur-CKB.umd.prod.js +1 -1
  71. package/dist/lang/lu.umd.prod.js +1 -1
  72. package/dist/lang/lv.umd.prod.js +1 -1
  73. package/dist/lang/ml.umd.prod.js +1 -1
  74. package/dist/lang/ms.umd.prod.js +1 -1
  75. package/dist/lang/nb-NO.umd.prod.js +1 -1
  76. package/dist/lang/nl.umd.prod.js +1 -1
  77. package/dist/lang/pl.umd.prod.js +1 -1
  78. package/dist/lang/pt-BR.umd.prod.js +1 -1
  79. package/dist/lang/pt.umd.prod.js +1 -1
  80. package/dist/lang/ro.umd.prod.js +1 -1
  81. package/dist/lang/ru.umd.prod.js +1 -1
  82. package/dist/lang/sk.umd.prod.js +1 -1
  83. package/dist/lang/sl.umd.prod.js +1 -1
  84. package/dist/lang/sr-CYR.umd.prod.js +1 -1
  85. package/dist/lang/sr.umd.prod.js +1 -1
  86. package/dist/lang/sv.umd.prod.js +1 -1
  87. package/dist/lang/ta.umd.prod.js +1 -1
  88. package/dist/lang/th.umd.prod.js +1 -1
  89. package/dist/lang/tr.umd.prod.js +1 -1
  90. package/dist/lang/ug.umd.prod.js +1 -1
  91. package/dist/lang/uk.umd.prod.js +1 -1
  92. package/dist/lang/vi.umd.prod.js +1 -1
  93. package/dist/lang/zh-CN.umd.prod.js +1 -1
  94. package/dist/lang/zh-TW.umd.prod.js +1 -1
  95. package/dist/quasar.cjs.prod.js +2 -2
  96. package/dist/quasar.esm.prod.js +2 -2
  97. package/dist/quasar.sass +1 -1
  98. package/dist/quasar.umd.js +123 -125
  99. package/dist/quasar.umd.prod.js +2 -2
  100. package/dist/ssr-directives/Morph.js +1 -1
  101. package/dist/types/index.d.ts +1824 -1522
  102. package/dist/vetur/quasar-attributes.json +18 -10
  103. package/dist/vetur/quasar-tags.json +2 -0
  104. package/dist/web-types/web-types.json +34 -16
  105. package/package.json +1 -1
  106. package/src/components/color/QColor.json +7 -2
  107. package/src/components/date/QDate.js +1 -1
  108. package/src/components/date/QDate.json +2 -2
  109. package/src/components/file/QFile.js +2 -1
  110. package/src/components/file/QFile.json +1 -1
  111. package/src/components/img/QImg.js +9 -13
  112. package/src/components/img/QImg.json +14 -0
  113. package/src/components/input/QInput.json +2 -2
  114. package/src/components/menu/QMenu.js +4 -1
  115. package/src/components/radio/QRadio.json +1 -1
  116. package/src/components/range/QRange.json +3 -3
  117. package/src/components/select/QSelect.js +23 -60
  118. package/src/components/select/QSelect.json +1 -1
  119. package/src/components/slider/QSlider.json +7 -2
  120. package/src/components/tabs/QTabs.js +41 -12
  121. package/src/components/tabs/QTabs.json +1 -1
  122. package/src/components/time/QTime.json +2 -2
  123. package/src/components/tooltip/QTooltip.js +4 -1
  124. package/src/components/virtual-scroll/use-virtual-scroll.js +4 -28
  125. package/src/composables/private/use-field.js +4 -6
  126. package/src/plugins/Loading.json +3 -2
  127. package/src/plugins/LoadingBar.js +4 -0
  128. package/src/plugins/Meta.js +16 -8
  129. package/src/plugins/Notify.js +3 -0
  130. package/src/utils/private/global-dialog.js +2 -1
  131. package/src/utils/private/rtl.js +27 -0
@@ -1,4 +1,4 @@
1
- import { h, defineComponent, ref, computed, watch, onBeforeUpdate, onUpdated, onBeforeMount, onBeforeUnmount, nextTick, getCurrentInstance } from 'vue'
1
+ import { h, defineComponent, ref, computed, watch, onBeforeUpdate, onUpdated, onBeforeUnmount, nextTick, getCurrentInstance } from 'vue'
2
2
 
3
3
  import QField from '../field/QField.js'
4
4
  import QIcon from '../icon/QIcon.js'
@@ -142,7 +142,7 @@ export default defineComponent({
142
142
  const dialogFieldFocused = ref(false)
143
143
  const innerLoadingIndicator = ref(false)
144
144
 
145
- let inputTimer, innerValueCache, optionScopeCache,
145
+ let inputTimer, innerValueCache,
146
146
  hasDialog, userInputValue, filterId, defaultInputValue,
147
147
  transitionShowComputed, searchBuffer, searchBufferExp
148
148
 
@@ -268,17 +268,28 @@ export default defineComponent({
268
268
  const tabindex = computed(() => (state.focused.value === true ? props.tabindex : -1))
269
269
 
270
270
  const comboboxAttrs = computed(() => ({
271
+ tabindex: tabindex.value,
271
272
  role: 'combobox',
272
- 'aria-multiselectable': props.multiple === true ? 'true' : 'false',
273
+ 'aria-label': props.label,
274
+ 'aria-autocomplete': props.useInput === true ? 'list' : 'none',
273
275
  'aria-expanded': menu.value === true ? 'true' : 'false',
274
276
  'aria-owns': `${ state.targetUid.value }_lb`,
275
- 'aria-activedescendant': `${ state.targetUid.value }_${ optionIndex.value }`
277
+ 'aria-controls': `${ state.targetUid.value }_lb`
276
278
  }))
277
279
 
278
- const listboxAttrs = computed(() => ({
279
- role: 'listbox',
280
- id: `${ state.targetUid.value }_lb`
281
- }))
280
+ const listboxAttrs = computed(() => {
281
+ const attrs = {
282
+ id: `${ state.targetUid.value }_lb`,
283
+ role: 'listbox',
284
+ 'aria-multiselectable': props.multiple === true ? 'true' : 'false'
285
+ }
286
+
287
+ if (optionIndex.value >= 0) {
288
+ attrs[ 'aria-activedescendant' ] = `${ state.targetUid.value }_${ optionIndex.value }`
289
+ }
290
+
291
+ return attrs
292
+ })
282
293
 
283
294
  const selectedScope = computed(() => {
284
295
  return innerValue.value.map((opt, i) => ({
@@ -298,7 +309,6 @@ export default defineComponent({
298
309
  }
299
310
 
300
311
  const { from, to } = virtualScrollSliceRange.value
301
- const { options, optionEls } = optionScopeCache
302
312
 
303
313
  return props.options.slice(from, to).map((opt, i) => {
304
314
  const disable = isOptionDisabled.value(opt) === true
@@ -330,7 +340,7 @@ export default defineComponent({
330
340
  }
331
341
  }
332
342
 
333
- const option = {
343
+ return {
334
344
  index,
335
345
  opt,
336
346
  html: needsHtmlFn.value(opt),
@@ -341,22 +351,6 @@ export default defineComponent({
341
351
  setOptionIndex,
342
352
  itemProps
343
353
  }
344
-
345
- const optionWithoutEvents = {
346
- ...option,
347
- itemProps: {
348
- ...itemProps,
349
- onClick: void 0,
350
- onMousemove: void 0
351
- }
352
- }
353
-
354
- if (options[ i ] === void 0 || isDeepEqual(optionWithoutEvents, options[ i ]) !== true) {
355
- options[ i ] = optionWithoutEvents
356
- optionEls[ i ] = void 0
357
- }
358
-
359
- return option
360
354
  })
361
355
  })
362
356
 
@@ -938,14 +932,6 @@ export default defineComponent({
938
932
  }
939
933
 
940
934
  function getAllOptions () {
941
- if (
942
- slots.option !== void 0
943
- && optionScopeCache.optionSlot !== slots.option
944
- ) {
945
- optionScopeCache.optionSlot = slots.option
946
- optionScopeCache.optionEls = []
947
- }
948
-
949
935
  const fn = slots.option !== void 0
950
936
  ? slots.option
951
937
  : scope => {
@@ -965,15 +951,7 @@ export default defineComponent({
965
951
  })
966
952
  }
967
953
 
968
- const { optionEls } = optionScopeCache
969
-
970
- let options = padVirtualScroll('div', optionScope.value.map((scope, i) => {
971
- if (optionEls[ i ] === void 0) {
972
- optionEls[ i ] = fn(scope)
973
- }
974
-
975
- return optionEls[ i ]
976
- }))
954
+ let options = padVirtualScroll('div', optionScope.value.map(fn))
977
955
 
978
956
  if (slots[ 'before-options' ] !== void 0) {
979
957
  options = slots[ 'before-options' ]().concat(options)
@@ -991,16 +969,15 @@ export default defineComponent({
991
969
  value: inputValue.value !== void 0 ? inputValue.value : '',
992
970
  // required for Android in order to show ENTER key when in form
993
971
  type: 'search',
972
+ ...comboboxAttrs.value,
994
973
  ...state.splitAttrs.attributes.value,
995
974
  id: state.targetUid.value,
996
975
  maxlength: props.maxlength,
997
- tabindex: props.tabindex,
998
976
  autocomplete: props.autocomplete,
999
977
  'data-autofocus': (fromDialog !== true && props.autofocus === true) || void 0,
1000
978
  disabled: props.disable === true,
1001
979
  readonly: props.readonly === true,
1002
- ...inputControlEvents.value,
1003
- ...comboboxAttrs.value
980
+ ...inputControlEvents.value
1004
981
  }
1005
982
 
1006
983
  if (fromDialog !== true && hasDialog === true) {
@@ -1286,10 +1263,6 @@ export default defineComponent({
1286
1263
  }
1287
1264
 
1288
1265
  function closeMenu () {
1289
- if (optionScopeCache !== void 0) {
1290
- optionScopeCache.optionEls = []
1291
- }
1292
-
1293
1266
  if (dialog.value === true) {
1294
1267
  return
1295
1268
  }
@@ -1405,16 +1378,7 @@ export default defineComponent({
1405
1378
 
1406
1379
  updatePreState()
1407
1380
 
1408
- onBeforeMount(() => {
1409
- optionScopeCache = {
1410
- optionSlot: slots.option,
1411
- options: [],
1412
- optionEls: []
1413
- }
1414
- })
1415
-
1416
1381
  onBeforeUnmount(() => {
1417
- optionScopeCache = void 0
1418
1382
  clearTimeout(inputTimer)
1419
1383
  })
1420
1384
 
@@ -1502,7 +1466,6 @@ export default defineComponent({
1502
1466
  key: 'd_t',
1503
1467
  class: 'no-outline',
1504
1468
  id: state.targetUid.value,
1505
- tabindex: props.tabindex,
1506
1469
  ...comboboxAttrs.value,
1507
1470
  onKeydown: onTargetKeydown,
1508
1471
  onKeyup: onTargetKeyup,
@@ -8,7 +8,7 @@
8
8
  "props": {
9
9
  "model-value": {
10
10
  "extends": "model-value",
11
- "type": [ "Number", "String", "Array" ],
11
+ "type": [ "Number", "String", "Array", "null", "undefined" ],
12
12
  "desc": "Model of the component; Must be Array if using 'multiple' prop; Either use this property (along with a listener for 'update:modelValue' event) OR use v-model directive",
13
13
  "examples": [ "v-model=\"myModel\"" ]
14
14
  },
@@ -8,7 +8,7 @@
8
8
  "props": {
9
9
  "model-value": {
10
10
  "extends": "model-value",
11
- "type": "Number",
11
+ "type": [ "Number", "null", "undefined" ],
12
12
  "desc": "Model of the component (must be between min/max); Either use this property (along with a listener for 'update:modelValue' event) OR use v-model directive",
13
13
  "examples": [ "v-model=\"positionModel\"" ]
14
14
  },
@@ -125,7 +125,12 @@
125
125
 
126
126
  "events": {
127
127
  "update:model-value": {
128
- "extends": "update:model-value"
128
+ "extends": "update:model-value",
129
+ "params": {
130
+ "value": {
131
+ "type": [ "Number", "null" ]
132
+ }
133
+ }
129
134
  },
130
135
 
131
136
  "change": {
@@ -9,6 +9,7 @@ import useTimeout from '../../composables/private/use-timeout.js'
9
9
  import { noop } from '../../utils/event.js'
10
10
  import { hSlot } from '../../utils/private/render.js'
11
11
  import { tabsKey } from '../../utils/private/symbols.js'
12
+ import { rtlHasScrollBug } from '../../utils/private/rtl.js'
12
13
 
13
14
  function getIndicatorClass (color, top, vertical) {
14
15
  const pos = vertical === true
@@ -136,6 +137,11 @@ export default defineComponent({
136
137
  : { container: 'width', content: 'offsetWidth', scroll: 'scrollWidth' }
137
138
  ))
138
139
 
140
+ const isRTL = computed(() => props.vertical !== true && $q.lang.rtl === true)
141
+ const rtlPosCorrection = computed(() => rtlHasScrollBug === false && isRTL.value === true)
142
+
143
+ watch(isRTL, localUpdateArrows)
144
+
139
145
  watch(() => props.modelValue, name => {
140
146
  updateModel({ name, setCurrent: true, skipEmit: true })
141
147
  })
@@ -278,12 +284,18 @@ export default defineComponent({
278
284
  if (content !== null) {
279
285
  const
280
286
  rect = content.getBoundingClientRect(),
281
- pos = props.vertical === true ? content.scrollTop : content.scrollLeft
287
+ pos = props.vertical === true ? content.scrollTop : Math.abs(content.scrollLeft)
282
288
 
283
- leftArrow.value = pos > 0
284
- rightArrow.value = props.vertical === true
285
- ? Math.ceil(pos + rect.height) < content.scrollHeight
286
- : Math.ceil(pos + rect.width) < content.scrollWidth
289
+ if (isRTL.value === true) {
290
+ leftArrow.value = Math.ceil(pos + rect.width) < content.scrollWidth - 1
291
+ rightArrow.value = pos > 0
292
+ }
293
+ else {
294
+ leftArrow.value = pos > 0
295
+ rightArrow.value = props.vertical === true
296
+ ? Math.ceil(pos + rect.height) < content.scrollHeight
297
+ : Math.ceil(pos + rect.width) < content.scrollWidth
298
+ }
287
299
  }
288
300
  }
289
301
 
@@ -292,33 +304,50 @@ export default defineComponent({
292
304
  scrollTowards(value)
293
305
 
294
306
  scrollTimer = setInterval(() => {
295
- if (scrollTowards(value)) {
307
+ if (scrollTowards(value) === true) {
296
308
  stopAnimScroll()
297
309
  }
298
310
  }, 5)
299
311
  }
300
312
 
301
313
  function scrollToStart () {
302
- animScrollTo(0)
314
+ animScrollTo(rtlPosCorrection.value === true ? 9999 : 0)
303
315
  }
304
316
 
305
317
  function scrollToEnd () {
306
- animScrollTo(9999)
318
+ animScrollTo(rtlPosCorrection.value === true ? 0 : 9999)
307
319
  }
308
320
 
309
321
  function stopAnimScroll () {
310
322
  clearInterval(scrollTimer)
311
323
  }
312
324
 
325
+ // let's speed up execution of time-sensitive scrollTowards()
326
+ // with a computed variable by directly applying the minimal
327
+ // number of instructions on get/set functions
328
+ const posFn = computed(() => (
329
+ rtlPosCorrection.value === true
330
+ ? { get: content => Math.abs(content.scrollLeft), set: (content, pos) => { content.scrollLeft = -pos } }
331
+ : (
332
+ props.vertical === true
333
+ ? { get: content => content.scrollTop, set: (content, pos) => { content.scrollTop = pos } }
334
+ : { get: content => content.scrollLeft, set: (content, pos) => { content.scrollLeft = pos } }
335
+ )
336
+ ))
337
+
313
338
  function scrollTowards (value) {
314
- const content = contentRef.value
339
+ const
340
+ content = contentRef.value,
341
+ { get, set } = posFn.value
342
+
315
343
  let
316
- pos = props.vertical === true ? content.scrollTop : content.scrollLeft,
317
- done = false
344
+ done = false,
345
+ pos = get(content)
318
346
 
319
347
  const direction = value < pos ? -1 : 1
320
348
 
321
349
  pos += direction * 5
350
+
322
351
  if (pos < 0) {
323
352
  done = true
324
353
  pos = 0
@@ -331,7 +360,7 @@ export default defineComponent({
331
360
  pos = value
332
361
  }
333
362
 
334
- content[ props.vertical === true ? 'scrollTop' : 'scrollLeft' ] = pos
363
+ set(content, pos)
335
364
  localUpdateArrows()
336
365
 
337
366
  return done
@@ -6,7 +6,7 @@
6
6
  "props": {
7
7
  "model-value":{
8
8
  "extends": "model-value",
9
- "type": [ "Number", "String" ],
9
+ "type": [ "Number", "String", "null", "undefined" ],
10
10
  "desc": "Model of the component defining current panel name; Either use this property (along with a listener for 'update:modelValue' event) OR use v-model directive",
11
11
  "required": false,
12
12
  "examples": [ "v-model=\"selectedTab\"" ]
@@ -8,7 +8,7 @@
8
8
  "props": {
9
9
  "model-value": {
10
10
  "extends": "model-value",
11
- "type": "String",
11
+ "type": [ "String", "null", "undefined" ],
12
12
  "desc": "Time of the component; Either use this property (along with a listener for 'update:modelValue' event) OR use v-model directive",
13
13
  "examples": [
14
14
  "v-model=\"currentTime\""
@@ -115,7 +115,7 @@
115
115
  "extends": "update:model-value",
116
116
  "params": {
117
117
  "value": {
118
- "type": "String"
118
+ "type": [ "String", "null" ]
119
119
  },
120
120
  "details": {
121
121
  "type": "Object",
@@ -286,7 +286,10 @@ export default defineComponent({
286
286
  'q-tooltip q-tooltip--style q-position-engine no-pointer-events',
287
287
  attrs.class
288
288
  ],
289
- style: transitionStyle.value,
289
+ style: [
290
+ attrs.style,
291
+ transitionStyle.value
292
+ ],
290
293
  role: 'complementary'
291
294
  }, hSlot(slots.default))
292
295
  : null
@@ -2,6 +2,7 @@ import { h, ref, computed, watch, onBeforeMount, onBeforeUnmount, nextTick, getC
2
2
 
3
3
  import debounce from '../../utils/debounce.js'
4
4
  import { noop } from '../../utils/event.js'
5
+ import { rtlHasScrollBug } from '../../utils/private/rtl.js'
5
6
 
6
7
  const aggBucketSize = 1000
7
8
 
@@ -15,31 +16,6 @@ const scrollToEdges = [
15
16
  ]
16
17
 
17
18
  const slice = Array.prototype.slice
18
-
19
- let buggyRTL = void 0
20
-
21
- // mobile Chrome takes the crown for this
22
- if (!__QUASAR_SSR__) {
23
- const scroller = document.createElement('div')
24
- const spacer = document.createElement('div')
25
-
26
- scroller.setAttribute('dir', 'rtl')
27
- scroller.style.width = '1px'
28
- scroller.style.height = '1px'
29
- scroller.style.overflow = 'auto'
30
-
31
- spacer.style.width = '1000px'
32
- spacer.style.height = '1px'
33
-
34
- document.body.appendChild(scroller)
35
- scroller.appendChild(spacer)
36
- scroller.scrollLeft = -1000
37
-
38
- buggyRTL = scroller.scrollLeft >= 0
39
-
40
- scroller.remove()
41
- }
42
-
43
19
  let id = 1
44
20
 
45
21
  const setOverflowAnchor = __QUASAR_SSR__ || window.getComputedStyle(document.body).overflowAnchor === void 0
@@ -99,7 +75,7 @@ function getScrollDetails (
99
75
  details.scrollMaxSize = parentCalc.scrollWidth
100
76
 
101
77
  if (rtl === true) {
102
- details.scrollStart = (buggyRTL === true ? details.scrollMaxSize - details.scrollViewSize : 0) - details.scrollStart
78
+ details.scrollStart = (rtlHasScrollBug === true ? details.scrollMaxSize - details.scrollViewSize : 0) - details.scrollStart
103
79
  }
104
80
  }
105
81
  else {
@@ -157,7 +133,7 @@ function setScroll (parent, scroll, horizontal, rtl) {
157
133
  if (parent === window) {
158
134
  if (horizontal === true) {
159
135
  if (rtl === true) {
160
- scroll = (buggyRTL === true ? document.body.scrollWidth - window.innerWidth : 0) - scroll
136
+ scroll = (rtlHasScrollBug === true ? document.body.scrollWidth - window.innerWidth : 0) - scroll
161
137
  }
162
138
  window.scrollTo(scroll, window.pageYOffset || window.scrollY || document.body.scrollTop || 0)
163
139
  }
@@ -167,7 +143,7 @@ function setScroll (parent, scroll, horizontal, rtl) {
167
143
  }
168
144
  else if (horizontal === true) {
169
145
  if (rtl === true) {
170
- scroll = (buggyRTL === true ? parent.scrollWidth - parent.offsetWidth : 0) - scroll
146
+ scroll = (rtlHasScrollBug === true ? parent.scrollWidth - parent.offsetWidth : 0) - scroll
171
147
  }
172
148
  parent.scrollLeft = scroll
173
149
  }
@@ -547,12 +547,10 @@ export default function (state) {
547
547
  return function renderField () {
548
548
  return h('label', {
549
549
  ref: state.rootRef,
550
- class: state.inheritAttrs !== true
551
- ? [
552
- classes.value,
553
- attrs.class
554
- ]
555
- : classes.value,
550
+ class: [
551
+ classes.value,
552
+ attrs.class
553
+ ],
556
554
  style: attrs.style,
557
555
  ...attributes.value
558
556
  }, [
@@ -45,8 +45,9 @@
45
45
  "desc": "Color name for background from the Quasar Color Palette"
46
46
  },
47
47
  "spinner": {
48
- "type": "Component",
49
- "desc": "One of the QSpinners"
48
+ "type": "String",
49
+ "desc": "One of the QSpinners",
50
+ "examples": [ "QSpinnerAudio" ]
50
51
  },
51
52
  "customClass": {
52
53
  "type": "String",
@@ -39,6 +39,10 @@ export default defineReactivePlugin({
39
39
 
40
40
  const vm = createChildApp({
41
41
  name: 'LoadingBar',
42
+
43
+ // hide App from Vue devtools
44
+ devtools: { hide: true },
45
+
42
46
  setup: () => () => h(QAjaxBar, props.value)
43
47
  }, parentApp).mount(el)
44
48
 
@@ -191,17 +191,25 @@ function injectServerMeta (ssrContext) {
191
191
 
192
192
  const ctx = ssrContext._meta
193
193
 
194
- ctx.htmlAttrs += Object.keys(data.htmlAttr)
195
- .filter(htmlFilter)
196
- .map(getAttr(data.htmlAttr))
197
- .join(' ')
194
+ const htmlAttr = Object.keys(data.htmlAttr).filter(htmlFilter)
195
+
196
+ if (htmlAttr.length > 0) {
197
+ ctx.htmlAttrs += (
198
+ (ctx.htmlAttrs.length > 0 ? ' ' : '')
199
+ + htmlAttr.map(getAttr(data.htmlAttr)).join(' ')
200
+ )
201
+ }
198
202
 
199
203
  ctx.headTags += getHead(data)
200
204
 
201
- ctx.bodyAttrs += Object.keys(data.bodyAttr)
202
- .filter(bodyFilter)
203
- .map(getAttr(data.bodyAttr))
204
- .join(' ')
205
+ const bodyAttr = Object.keys(data.bodyAttr).filter(bodyFilter)
206
+
207
+ if (bodyAttr.length > 0) {
208
+ ctx.bodyAttrs += (
209
+ (ctx.bodyAttrs.length > 0 ? ' ' : '')
210
+ + bodyAttr.map(getAttr(data.bodyAttr)).join(' ')
211
+ )
212
+ }
205
213
 
206
214
  ctx.bodyTags += Object.keys(data.noscript)
207
215
  .map(name => `<noscript data-qmeta="${ name }">${ data.noscript[ name ] }</noscript>`)
@@ -64,6 +64,9 @@ function logError (error, config) {
64
64
  function getComponent ($q) {
65
65
  return defineComponent({
66
66
  name: 'QNotifications',
67
+
68
+ // hide App from Vue devtools
69
+ devtools: { hide: true },
67
70
 
68
71
  setup () {
69
72
  const notificationsList = {}
@@ -5,7 +5,8 @@ import { createGlobalNode, removeGlobalNode } from './global-nodes.js'
5
5
 
6
6
  const ssrAPI = {
7
7
  onOk: () => ssrAPI,
8
- okCancel: () => ssrAPI,
8
+ onCancel: () => ssrAPI,
9
+ onDismiss: () => ssrAPI,
9
10
  hide: () => ssrAPI,
10
11
  update: () => ssrAPI
11
12
  }
@@ -0,0 +1,27 @@
1
+ let rtlHasScrollBug = false
2
+
3
+ // mobile Chrome takes the crown for this
4
+ if (!__QUASAR_SSR__) {
5
+ const scroller = document.createElement('div')
6
+ const spacer = document.createElement('div')
7
+
8
+ scroller.setAttribute('dir', 'rtl')
9
+ scroller.style.width = '1px'
10
+ scroller.style.height = '1px'
11
+ scroller.style.overflow = 'auto'
12
+
13
+ spacer.style.width = '1000px'
14
+ spacer.style.height = '1px'
15
+
16
+ document.body.appendChild(scroller)
17
+ scroller.appendChild(spacer)
18
+ scroller.scrollLeft = -1000
19
+
20
+ rtlHasScrollBug = scroller.scrollLeft >= 0
21
+
22
+ scroller.remove()
23
+ }
24
+
25
+ export {
26
+ rtlHasScrollBug
27
+ }