quasar 1.18.3 → 1.18.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 (175) hide show
  1. package/dist/api/BottomSheet.json +1 -1
  2. package/dist/api/Notify.json +205 -5
  3. package/dist/api/QAvatar.json +1 -1
  4. package/dist/api/QBreadcrumbsEl.json +1 -1
  5. package/dist/api/QBtn.json +2 -2
  6. package/dist/api/QBtnDropdown.json +3 -3
  7. package/dist/api/QCarousel.json +3 -3
  8. package/dist/api/QChip.json +4 -4
  9. package/dist/api/QExpansionItem.json +2 -2
  10. package/dist/api/QFab.json +2 -2
  11. package/dist/api/QFabAction.json +1 -1
  12. package/dist/api/QIcon.json +4 -2
  13. package/dist/api/QKnob.json +23 -0
  14. package/dist/api/QPagination.json +4 -4
  15. package/dist/api/QRange.json +1 -1
  16. package/dist/api/QRouteTab.json +1 -1
  17. package/dist/api/QSelect.json +1 -1
  18. package/dist/api/QSlider.json +1 -1
  19. package/dist/api/QStep.json +4 -4
  20. package/dist/api/QStepper.json +4 -4
  21. package/dist/api/QTab.json +1 -1
  22. package/dist/api/QTimelineEntry.json +1 -1
  23. package/dist/api/QToggle.json +1 -1
  24. package/dist/api/QTree.json +1 -1
  25. package/dist/icon-set/bootstrap-icons.umd.min.js +1 -1
  26. package/dist/icon-set/eva-icons.umd.min.js +1 -1
  27. package/dist/icon-set/fontawesome-v5-pro.umd.min.js +1 -1
  28. package/dist/icon-set/fontawesome-v5.umd.min.js +1 -1
  29. package/dist/icon-set/fontawesome-v6-pro.umd.min.js +6 -0
  30. package/dist/icon-set/fontawesome-v6.umd.min.js +6 -0
  31. package/dist/icon-set/ionicons-v4.umd.min.js +1 -1
  32. package/dist/icon-set/line-awesome.umd.min.js +1 -1
  33. package/dist/icon-set/material-icons-outlined.umd.min.js +1 -1
  34. package/dist/icon-set/material-icons-round.umd.min.js +1 -1
  35. package/dist/icon-set/material-icons-sharp.umd.min.js +1 -1
  36. package/dist/icon-set/material-icons.umd.min.js +1 -1
  37. package/dist/icon-set/mdi-v3.umd.min.js +1 -1
  38. package/dist/icon-set/mdi-v4.umd.min.js +1 -1
  39. package/dist/icon-set/mdi-v5.umd.min.js +1 -1
  40. package/dist/icon-set/mdi-v6.umd.min.js +1 -1
  41. package/dist/icon-set/svg-bootstrap-icons.umd.min.js +2 -2
  42. package/dist/icon-set/svg-eva-icons.umd.min.js +2 -2
  43. package/dist/icon-set/svg-fontawesome-v5.umd.min.js +2 -2
  44. package/dist/icon-set/svg-fontawesome-v6.umd.min.js +6 -0
  45. package/dist/icon-set/svg-ionicons-v4.umd.min.js +1 -1
  46. package/dist/icon-set/svg-ionicons-v5.umd.min.js +1 -1
  47. package/dist/icon-set/svg-ionicons-v6.umd.min.js +2 -2
  48. package/dist/icon-set/svg-line-awesome.umd.min.js +1 -1
  49. package/dist/icon-set/svg-material-icons-outlined.umd.min.js +1 -1
  50. package/dist/icon-set/svg-material-icons-round.umd.min.js +1 -1
  51. package/dist/icon-set/svg-material-icons-sharp.umd.min.js +1 -1
  52. package/dist/icon-set/svg-material-icons.umd.min.js +1 -1
  53. package/dist/icon-set/svg-mdi-v4.umd.min.js +1 -1
  54. package/dist/icon-set/svg-mdi-v5.umd.min.js +1 -1
  55. package/dist/icon-set/svg-mdi-v6.umd.min.js +2 -2
  56. package/dist/icon-set/svg-themify.umd.min.js +1 -1
  57. package/dist/icon-set/themify.umd.min.js +1 -1
  58. package/dist/lang/ar.umd.min.js +1 -1
  59. package/dist/lang/az-latn.umd.min.js +1 -1
  60. package/dist/lang/bg.umd.min.js +1 -1
  61. package/dist/lang/ca.umd.min.js +1 -1
  62. package/dist/lang/cs.umd.min.js +1 -1
  63. package/dist/lang/da.umd.min.js +1 -1
  64. package/dist/lang/de.umd.min.js +1 -1
  65. package/dist/lang/el.umd.min.js +1 -1
  66. package/dist/lang/en-gb.umd.min.js +1 -1
  67. package/dist/lang/en-us.umd.min.js +1 -1
  68. package/dist/lang/eo.umd.min.js +1 -1
  69. package/dist/lang/es.umd.min.js +1 -1
  70. package/dist/lang/et.umd.min.js +1 -1
  71. package/dist/lang/eu.umd.min.js +6 -0
  72. package/dist/lang/fa-ir.umd.min.js +1 -1
  73. package/dist/lang/fa.umd.min.js +1 -1
  74. package/dist/lang/fi.umd.min.js +1 -1
  75. package/dist/lang/fr.umd.min.js +1 -1
  76. package/dist/lang/gn.umd.min.js +1 -1
  77. package/dist/lang/he.umd.min.js +1 -1
  78. package/dist/lang/hr.umd.min.js +1 -1
  79. package/dist/lang/hu.umd.min.js +1 -1
  80. package/dist/lang/id.umd.min.js +1 -1
  81. package/dist/lang/is.umd.min.js +1 -1
  82. package/dist/lang/it.umd.min.js +1 -1
  83. package/dist/lang/ja.umd.min.js +1 -1
  84. package/dist/lang/km.umd.min.js +1 -1
  85. package/dist/lang/ko-kr.umd.min.js +1 -1
  86. package/dist/lang/kur-ckb.umd.min.js +1 -1
  87. package/dist/lang/kz.umd.min.js +6 -0
  88. package/dist/lang/lu.umd.min.js +1 -1
  89. package/dist/lang/lv.umd.min.js +1 -1
  90. package/dist/lang/ml.umd.min.js +1 -1
  91. package/dist/lang/ms.umd.min.js +1 -1
  92. package/dist/lang/my.umd.min.js +1 -1
  93. package/dist/lang/nb-no.umd.min.js +1 -1
  94. package/dist/lang/nl.umd.min.js +1 -1
  95. package/dist/lang/pl.umd.min.js +1 -1
  96. package/dist/lang/pt-br.umd.min.js +1 -1
  97. package/dist/lang/pt.umd.min.js +1 -1
  98. package/dist/lang/ro.umd.min.js +1 -1
  99. package/dist/lang/ru.umd.min.js +1 -1
  100. package/dist/lang/sk.umd.min.js +1 -1
  101. package/dist/lang/sl.umd.min.js +1 -1
  102. package/dist/lang/sr.umd.min.js +1 -1
  103. package/dist/lang/sv.umd.min.js +1 -1
  104. package/dist/lang/ta.umd.min.js +1 -1
  105. package/dist/lang/th.umd.min.js +1 -1
  106. package/dist/lang/tr.umd.min.js +1 -1
  107. package/dist/lang/ug.umd.min.js +2 -2
  108. package/dist/lang/uk.umd.min.js +1 -1
  109. package/dist/lang/vi.umd.min.js +1 -1
  110. package/dist/lang/zh-hans.umd.min.js +1 -1
  111. package/dist/lang/zh-hant.umd.min.js +1 -1
  112. package/dist/quasar.addon.css +1 -1
  113. package/dist/quasar.addon.rtl.css +1 -1
  114. package/dist/quasar.common.js +2 -2
  115. package/dist/quasar.css +6 -3
  116. package/dist/quasar.esm.js +2 -2
  117. package/dist/quasar.ie.polyfills.js +1 -1
  118. package/dist/quasar.ie.polyfills.umd.min.js +1 -1
  119. package/dist/quasar.min.css +1 -1
  120. package/dist/quasar.rtl.css +8 -3
  121. package/dist/quasar.rtl.min.css +1 -1
  122. package/dist/quasar.sass +4 -1
  123. package/dist/quasar.styl +4 -1
  124. package/dist/quasar.umd.js +212 -159
  125. package/dist/quasar.umd.min.js +2 -2
  126. package/dist/quasar.umd.modern.js +214 -159
  127. package/dist/quasar.umd.modern.min.js +2 -2
  128. package/dist/types/extras/icon-set.d.ts +2 -0
  129. package/dist/types/index.d.ts +122 -44
  130. package/dist/vetur/quasar-attributes.json +50 -38
  131. package/dist/vetur/quasar-tags.json +3 -0
  132. package/dist/web-types/web-types.json +69 -41
  133. package/icon-set/fontawesome-v6-pro.js +128 -0
  134. package/icon-set/fontawesome-v6.js +128 -0
  135. package/icon-set/svg-fontawesome-v6.js +198 -0
  136. package/lang/eu.js +93 -0
  137. package/lang/index.json +8 -0
  138. package/lang/kz.js +97 -0
  139. package/lang/ug.js +49 -52
  140. package/package.json +1 -1
  141. package/src/api.extends.json +1 -1
  142. package/src/components/btn/QBtn.js +30 -22
  143. package/src/components/date/QDate.js +2 -1
  144. package/src/components/dialog-plugin/DialogPlugin.js +6 -5
  145. package/src/components/field/QField.js +17 -9
  146. package/src/components/file/QFile.js +1 -0
  147. package/src/components/icon/QIcon.js +6 -2
  148. package/src/components/icon/QIcon.json +1 -3
  149. package/src/components/input/QInput.js +4 -1
  150. package/src/components/knob/QKnob.js +46 -25
  151. package/src/components/knob/QKnob.json +22 -0
  152. package/src/components/linear-progress/QLinearProgress.sass +1 -0
  153. package/src/components/linear-progress/QLinearProgress.styl +1 -0
  154. package/src/components/select/QSelect.js +12 -9
  155. package/src/components/slide-transition/QSlideTransition.js +4 -4
  156. package/src/components/slider/slider-utils.js +4 -4
  157. package/src/components/slider/slider-utils.json +1 -1
  158. package/src/components/stepper/QStep.json +3 -0
  159. package/src/components/stepper/QStepper.json +3 -0
  160. package/src/components/stepper/QStepper.sass +2 -0
  161. package/src/components/stepper/QStepper.styl +2 -0
  162. package/src/components/stepper/StepHeader.js +23 -8
  163. package/src/components/table/table-sort.js +2 -2
  164. package/src/components/uploader/QUploaderBase.js +4 -1
  165. package/src/mixins/datetime.js +3 -1
  166. package/src/mixins/file.js +2 -1
  167. package/src/mixins/mask.js +1 -1
  168. package/src/plugins/Loading.js +3 -2
  169. package/src/plugins/LoadingBar.js +15 -10
  170. package/src/plugins/Notify.js +8 -5
  171. package/src/plugins/Notify.json +100 -0
  172. package/src/utils/extend.js +12 -40
  173. package/src/utils/is.js +4 -14
  174. package/src/utils/morph.js +4 -3
  175. package/src/utils/web-storage.js +3 -2
@@ -47,7 +47,7 @@
47
47
 
48
48
  "icon": {
49
49
  "type": "String",
50
- "desc": "Icon name following Quasar convention; Make sure you have the icon library installed unless you are using 'img:' prefix",
50
+ "desc": "Icon name following Quasar convention; Make sure you have the icon library installed unless you are using 'img:' prefix; If 'none' (String) is used as value then no icon is rendered (but screen real estate will still be used for it)",
51
51
  "examples": [
52
52
  "map",
53
53
  "ion-add",
@@ -155,32 +155,39 @@ export default Vue.extend({
155
155
  },
156
156
 
157
157
  __onKeydown (e) {
158
- if (isKeyCode(e, [ 13, 32 ]) === true) {
159
- stopAndPrevent(e)
158
+ this.$emit('keydown', e)
160
159
 
160
+ if (isKeyCode(e, [ 13, 32 ]) === true) {
161
161
  if (keyboardTarget !== this.$el) {
162
162
  keyboardTarget !== void 0 && this.__cleanup()
163
163
 
164
- // focus external button if the focus helper was focused before
165
- this.$el.focus()
164
+ if (e.defaultPrevented !== true) {
165
+ // focus external button if the focus helper was focused before
166
+ this.$el.focus()
166
167
 
167
- keyboardTarget = this.$el
168
- this.$el.classList.add('q-btn--active')
169
- document.addEventListener('keyup', this.__onPressEnd, true)
170
- this.$el.addEventListener('blur', this.__onPressEnd, passiveCapture)
168
+ keyboardTarget = this.$el
169
+ this.$el.classList.add('q-btn--active')
170
+ document.addEventListener('keyup', this.__onPressEnd, true)
171
+ this.$el.addEventListener('blur', this.__onPressEnd, passiveCapture)
172
+ }
171
173
  }
172
- }
173
174
 
174
- this.$emit('keydown', e)
175
+ stopAndPrevent(e)
176
+ }
175
177
  },
176
178
 
177
179
  __onTouchstart (e) {
180
+ this.$emit('touchstart', e)
181
+
178
182
  if (touchTarget !== this.$el) {
179
183
  touchTarget !== void 0 && this.__cleanup()
180
- touchTarget = this.$el
181
- const target = this.touchTargetEl = e.target
182
- target.addEventListener('touchcancel', this.__onPressEnd, passiveCapture)
183
- target.addEventListener('touchend', this.__onPressEnd, passiveCapture)
184
+
185
+ if (e.defaultPrevented !== true) {
186
+ touchTarget = this.$el
187
+ const target = this.touchTargetEl = e.target
188
+ target.addEventListener('touchcancel', this.__onPressEnd, passiveCapture)
189
+ target.addEventListener('touchend', this.__onPressEnd, passiveCapture)
190
+ }
184
191
  }
185
192
 
186
193
  // avoid duplicated mousedown event
@@ -190,20 +197,21 @@ export default Vue.extend({
190
197
  this.mouseTimer = setTimeout(() => {
191
198
  this.avoidMouseRipple = false
192
199
  }, 200)
193
-
194
- this.$emit('touchstart', e)
195
200
  },
196
201
 
197
202
  __onMousedown (e) {
203
+ e.qSkipRipple = this.avoidMouseRipple === true
204
+ this.$emit('mousedown', e)
205
+
198
206
  if (mouseTarget !== this.$el) {
199
207
  mouseTarget !== void 0 && this.__cleanup()
200
- mouseTarget = this.$el
201
- this.$el.classList.add('q-btn--active')
202
- document.addEventListener('mouseup', this.__onPressEnd, passiveCapture)
203
- }
204
208
 
205
- e.qSkipRipple = this.avoidMouseRipple === true
206
- this.$emit('mousedown', e)
209
+ if (e.defaultPrevented !== true) {
210
+ mouseTarget = this.$el
211
+ this.$el.classList.add('q-btn--active')
212
+ document.addEventListener('mouseup', this.__onPressEnd, passiveCapture)
213
+ }
214
+ }
207
215
  },
208
216
 
209
217
  __onPressEnd (e) {
@@ -8,6 +8,7 @@ import { formatDate, __splitDate, getDateDiff } from '../../utils/date.js'
8
8
  import { pad } from '../../utils/format.js'
9
9
  import { jalaaliMonthLength, toGregorian } from '../../utils/date-persian.js'
10
10
  import cache from '../../utils/cache.js'
11
+ import { isObject } from '../../utils/is.js'
11
12
 
12
13
  const yearsInterval = 20
13
14
  const views = [ 'Calendar', 'Years', 'Months' ]
@@ -161,7 +162,7 @@ export default Vue.extend({
161
162
  rangeModel () {
162
163
  const fn = date => this.__decodeString(date, this.innerMask, this.innerLocale)
163
164
  return this.normalizedModel
164
- .filter(date => Object(date) === date && date.from !== void 0 && date.to !== void 0)
165
+ .filter(date => isObject(date) === true && date.from !== void 0 && date.to !== void 0)
165
166
  .map(range => ({ from: fn(range.from), to: fn(range.to) }))
166
167
  .filter(range => range.from.dateHash !== null && range.to.dateHash !== null && range.from.dateHash < range.to.dateHash)
167
168
  },
@@ -20,6 +20,7 @@ import DarkMixin from '../../mixins/dark.js'
20
20
  import AttrsMixin from '../../mixins/attrs.js'
21
21
 
22
22
  import cache from '../../utils/cache.js'
23
+ import { isObject } from '../../utils/is.js'
23
24
 
24
25
  export default Vue.extend({
25
26
  name: 'DialogPlugin',
@@ -64,7 +65,7 @@ export default Vue.extend({
64
65
 
65
66
  spinner () {
66
67
  if (this.progress !== false) {
67
- return Object(this.progress) === this.progress
68
+ return isObject(this.progress) === true
68
69
  ? {
69
70
  component: this.progress.spinner || QSpinner,
70
71
  props: { color: this.progress.color || this.vmColor }
@@ -81,7 +82,7 @@ export default Vue.extend({
81
82
  },
82
83
 
83
84
  okLabel () {
84
- return Object(this.ok) === this.ok
85
+ return isObject(this.ok) === true
85
86
  ? this.$q.lang.label.ok
86
87
  : (
87
88
  this.ok === true
@@ -91,7 +92,7 @@ export default Vue.extend({
91
92
  },
92
93
 
93
94
  cancelLabel () {
94
- return Object(this.cancel) === this.cancel
95
+ return isObject(this.cancel) === true
95
96
  ? this.$q.lang.label.cancel
96
97
  : (
97
98
  this.cancel === true
@@ -121,7 +122,7 @@ export default Vue.extend({
121
122
  label: this.okLabel,
122
123
  ripple: false,
123
124
  disable: this.okDisabled,
124
- ...(Object(this.ok) === this.ok ? this.ok : { flat: true })
125
+ ...(isObject(this.ok) === true ? this.ok : { flat: true })
125
126
  }
126
127
  },
127
128
 
@@ -130,7 +131,7 @@ export default Vue.extend({
130
131
  color: this.vmColor,
131
132
  label: this.cancelLabel,
132
133
  ripple: false,
133
- ...(Object(this.cancel) === this.cancel ? this.cancel : { flat: true })
134
+ ...(isObject(this.cancel) === true ? this.cancel : { flat: true })
134
135
  }
135
136
  }
136
137
  },
@@ -288,14 +288,6 @@ export default Vue.extend({
288
288
  }, this.__getControlContainer(h))
289
289
  )
290
290
 
291
- this.$scopedSlots.append !== void 0 && node.push(
292
- h('div', {
293
- staticClass: 'q-field__append q-field__marginal row no-wrap items-center',
294
- key: 'append',
295
- on: this.slotsEvents
296
- }, this.$scopedSlots.append())
297
- )
298
-
299
291
  this.hasError === true && this.noErrorIcon === false && node.push(
300
292
  this.__getInnerAppendNode(h, 'error', [
301
293
  h(QIcon, { props: { name: this.$q.iconSet.field.error, color: 'negative' } })
@@ -326,6 +318,14 @@ export default Vue.extend({
326
318
  )
327
319
  }
328
320
 
321
+ this.$scopedSlots.append !== void 0 && node.push(
322
+ h('div', {
323
+ staticClass: 'q-field__append q-field__marginal row no-wrap items-center',
324
+ key: 'append',
325
+ on: this.slotsEvents
326
+ }, this.$scopedSlots.append())
327
+ )
328
+
329
329
  this.__getInnerAppend !== void 0 && node.push(
330
330
  this.__getInnerAppendNode(h, 'inner-append', this.__getInnerAppend(h))
331
331
  )
@@ -539,10 +539,18 @@ export default Vue.extend({
539
539
  this.__onPreRender !== void 0 && this.__onPreRender()
540
540
  this.__onPostRender !== void 0 && this.$nextTick(this.__onPostRender)
541
541
 
542
+ const attrs = this.__getControl === void 0 && this.$scopedSlots.control === void 0
543
+ ? {
544
+ ...this.qAttrs,
545
+ 'data-autofocus': this.autofocus,
546
+ ...this.attrs
547
+ }
548
+ : this.attrs
549
+
542
550
  return h('label', {
543
551
  staticClass: 'q-field q-validation-component row no-wrap items-start',
544
552
  class: this.classes,
545
- attrs: this.attrs
553
+ attrs
546
554
  }, [
547
555
  this.$scopedSlots.before !== void 0 ? h('div', {
548
556
  staticClass: 'q-field__before q-field__marginal row no-wrap items-center',
@@ -167,6 +167,7 @@ export default Vue.extend({
167
167
  if (this.editable === true) {
168
168
  data.on = cache(this, 'native', {
169
169
  dragover: this.__onDragOver,
170
+ dragleave: this.__onDragLeave,
170
171
  keydown: this.__onKeydown,
171
172
  keyup: this.__onKeyup
172
173
  })
@@ -37,6 +37,7 @@ const imgRE = /^img:/
37
37
  const svgUseRE = /^svguse:/
38
38
  const ionRE = /^ion-/
39
39
  const faLaRE = /^[lf]a[srlbdk]? /
40
+ const fa6RE = /^fa-(brand|regular|solid)/
40
41
 
41
42
  export default Vue.extend({
42
43
  name: 'QIcon',
@@ -67,7 +68,7 @@ export default Vue.extend({
67
68
  let cls
68
69
  let icon = this.name
69
70
 
70
- if (!icon) {
71
+ if (icon === 'none' || !icon) {
71
72
  return { none: true }
72
73
  }
73
74
 
@@ -76,6 +77,9 @@ export default Vue.extend({
76
77
  if (res !== void 0) {
77
78
  if (res.icon !== void 0) {
78
79
  icon = res.icon
80
+ if (icon === 'none' || !icon) {
81
+ return { none: true }
82
+ }
79
83
  }
80
84
  else {
81
85
  return {
@@ -127,7 +131,7 @@ export default Vue.extend({
127
131
  if (matches !== null) {
128
132
  cls = libMap[ matches[ 1 ] ](icon)
129
133
  }
130
- else if (faLaRE.test(icon) === true) {
134
+ else if (faLaRE.test(icon) === true || fa6RE.test(icon) === true) {
131
135
  cls = icon
132
136
  }
133
137
  else if (ionRE.test(icon) === true) {
@@ -18,9 +18,7 @@
18
18
  },
19
19
 
20
20
  "name": {
21
- "type": "String",
22
- "desc": "Name of the icon, following Quasar convention",
23
- "examples": [ "map", "ion-add" ],
21
+ "extends": "icon",
24
22
  "category": "model"
25
23
  },
26
24
 
@@ -46,7 +46,10 @@ export default Vue.extend({
46
46
  if (this.hasMask === true) {
47
47
  if (this.stopValueWatcher === true) {
48
48
  this.stopValueWatcher = false
49
- return
49
+
50
+ if (String(v) === this.emitCachedValue) {
51
+ return
52
+ }
50
53
  }
51
54
 
52
55
  this.__updateMaskValue(v)
@@ -25,6 +25,9 @@ export default Vue.extend({
25
25
  },
26
26
 
27
27
  props: {
28
+ innerMin: Number,
29
+ innerMax: Number,
30
+
28
31
  step: {
29
32
  type: Number,
30
33
  default: 1,
@@ -41,31 +44,22 @@ export default Vue.extend({
41
44
  },
42
45
 
43
46
  data () {
47
+ const innerMin = this.__getInnerMin(this.innerMin)
48
+ const innerMax = this.__getInnerMax(this.innerMax)
49
+
44
50
  return {
45
- model: this.value,
51
+ model: this.value === null ? innerMin : between(this.value, innerMin, innerMax),
46
52
  dragging: false
47
53
  }
48
54
  },
49
55
 
50
56
  watch: {
51
- value (value) {
52
- if (value < this.min) {
53
- this.model = this.min
54
- }
55
- else if (value > this.max) {
56
- this.model = this.max
57
- }
58
- else {
59
- if (value !== this.model) {
60
- this.model = value
61
- }
62
- return
63
- }
57
+ modelUpdate () {
58
+ this.model = this.value === null
59
+ ? this.computedInnerMin
60
+ : between(this.value, this.computedInnerMin, this.computedInnerMax)
64
61
 
65
- if (this.model !== this.value) {
66
- this.$emit('input', this.model)
67
- this.$emit('change', this.model)
68
- }
62
+ this.__updateValue(true)
69
63
  }
70
64
  },
71
65
 
@@ -78,6 +72,18 @@ export default Vue.extend({
78
72
  )
79
73
  },
80
74
 
75
+ computedInnerMin () {
76
+ return this.__getInnerMin(this.innerMin)
77
+ },
78
+
79
+ computedInnerMax () {
80
+ return this.__getInnerMax(this.innerMax)
81
+ },
82
+
83
+ modelUpdate () {
84
+ return `${this.value}|${this.computedInnerMin}|${this.computedInnerMax}`
85
+ },
86
+
81
87
  editable () {
82
88
  return this.disable === false && this.readonly === false
83
89
  },
@@ -109,8 +115,8 @@ export default Vue.extend({
109
115
  attrs () {
110
116
  const attrs = {
111
117
  role: 'slider',
112
- 'aria-valuemin': this.min,
113
- 'aria-valuemax': this.max,
118
+ 'aria-valuemin': this.computedInnerMin,
119
+ 'aria-valuemax': this.computedInnerMax,
114
120
  'aria-valuenow': this.value
115
121
  }
116
122
 
@@ -126,6 +132,18 @@ export default Vue.extend({
126
132
  },
127
133
 
128
134
  methods: {
135
+ __getInnerMin (val) {
136
+ return isNaN(val) === true || this.innerMin < this.min
137
+ ? this.min
138
+ : this.innerMin
139
+ },
140
+
141
+ __getInnerMax (val) {
142
+ return isNaN(val) === true || val > this.max
143
+ ? this.max
144
+ : this.innerMax
145
+ },
146
+
129
147
  __updateCenterPosition () {
130
148
  const { top, left, width, height } = this.$el.getBoundingClientRect()
131
149
  this.centerPosition = {
@@ -167,8 +185,8 @@ export default Vue.extend({
167
185
 
168
186
  this.model = between(
169
187
  parseFloat((this.model + offset).toFixed(this.decimals)),
170
- this.min,
171
- this.max
188
+ this.computedInnerMin,
189
+ this.computedInnerMax
172
190
  )
173
191
 
174
192
  this.__updateValue()
@@ -204,11 +222,14 @@ export default Vue.extend({
204
222
  angle = center.left < pos.left ? angle + 90 : 270 - angle
205
223
  }
206
224
 
207
- if (this.angle) {
225
+ if (this.$q.lang.rtl === true) {
226
+ angle = normalizeToInterval(-angle - this.angle, 0, 360)
227
+ }
228
+ else if (this.angle) {
208
229
  angle = normalizeToInterval(angle - this.angle, 0, 360)
209
230
  }
210
231
 
211
- if (this.$q.lang.rtl === true) {
232
+ if (this.reverse === true) {
212
233
  angle = 360 - angle
213
234
  }
214
235
 
@@ -225,7 +246,7 @@ export default Vue.extend({
225
246
  model = parseFloat(model.toFixed(this.decimals))
226
247
  }
227
248
 
228
- model = between(model, this.min, this.max)
249
+ model = between(model, this.computedInnerMin, this.computedInnerMax)
229
250
 
230
251
  this.$emit('drag-value', model)
231
252
 
@@ -27,6 +27,22 @@
27
27
  "category": "model"
28
28
  },
29
29
 
30
+ "inner-min": {
31
+ "type": "Number",
32
+ "desc": "Inner minimum value of the model; Use in case you need the model value to be inside of the track's min-max values; Needs to be higher or equal to 'min' prop; Defaults to 'min' prop",
33
+ "examples": [ ":inner-min=\"0\"" ],
34
+ "category": "model",
35
+ "addedIn": "v1.18.4"
36
+ },
37
+
38
+ "inner-max": {
39
+ "type": "Number",
40
+ "desc": "Inner maximum value of the model; Use in case you need the model value to be inside of the track's min-max values; Needs to be lower or equal to 'max' prop; Defaults to 'max' prop",
41
+ "examples": [ ":inner-max=\"100\"" ],
42
+ "category": "model",
43
+ "addedIn": "v1.18.4"
44
+ },
45
+
30
46
  "step": {
31
47
  "type": "Number",
32
48
  "default": "1",
@@ -35,6 +51,12 @@
35
51
  "category": "model"
36
52
  },
37
53
 
54
+ "reverse": {
55
+ "type": "Boolean",
56
+ "desc": "Reverses the direction of progress",
57
+ "category": "behavior"
58
+ },
59
+
38
60
  "instant-feedback": {
39
61
  "type": "Boolean",
40
62
  "desc": "No animation when model changes",
@@ -6,6 +6,7 @@
6
6
  height: 1em
7
7
  color: $primary
8
8
  color: var(--q-color-primary)
9
+ transform: scale3d(1, 1, 1)
9
10
 
10
11
  &__model, &__track
11
12
  transform-origin: 0 0
@@ -6,6 +6,7 @@
6
6
  height: 1em
7
7
  color: $primary
8
8
  color: var(--q-color-primary)
9
+ transform: scale3d(1, 1, 1)
9
10
 
10
11
  &__model, &__track
11
12
  transform-origin: 0 0
@@ -302,7 +302,7 @@ export default Vue.extend({
302
302
  }
303
303
 
304
304
  if (this.$q.platform.is.desktop === true) {
305
- itemEvents.mousemove = () => { this.setOptionIndex(index) }
305
+ itemEvents.mousemove = () => { this.menu === true && this.setOptionIndex(index) }
306
306
  }
307
307
 
308
308
  const option = {
@@ -589,9 +589,7 @@ export default Vue.extend({
589
589
 
590
590
  return typeof val === 'function'
591
591
  ? val
592
- : opt => Object(opt) === opt && val in opt
593
- ? opt[val]
594
- : opt
592
+ : opt => (opt !== null && typeof opt === 'object' && val in opt ? opt[ val ] : opt)
595
593
  },
596
594
 
597
595
  isOptionSelected (opt) {
@@ -948,6 +946,8 @@ export default Vue.extend({
948
946
  }
949
947
  // there can be only one (when dialog is opened the control in dialog should be target)
950
948
  else if (this.editable === true) {
949
+ const attrs = isTarget === true ? this.comboboxAttrs : void 0
950
+
951
951
  child.push(
952
952
  h('div', {
953
953
  ref: isTarget === true ? 'target' : void 0,
@@ -956,7 +956,7 @@ export default Vue.extend({
956
956
  attrs: {
957
957
  id: isTarget === true ? this.targetUid : void 0,
958
958
  tabindex: this.tabindex,
959
- ...this.comboboxAttrs
959
+ ...attrs
960
960
  },
961
961
  on: cache(this, 'f-tget', {
962
962
  keydown: this.__onTargetKeydown,
@@ -995,7 +995,9 @@ export default Vue.extend({
995
995
  )
996
996
  }
997
997
 
998
- return h('div', { staticClass: 'q-field__native row items-center', attrs: this.qAttrs }, child)
998
+ const attrs = this.useInput === true || isTarget !== true ? void 0 : this.qAttrs
999
+
1000
+ return h('div', { staticClass: 'q-field__native row items-center', attrs }, child)
999
1001
  },
1000
1002
 
1001
1003
  __getOptions (h) {
@@ -1057,6 +1059,8 @@ export default Vue.extend({
1057
1059
  },
1058
1060
 
1059
1061
  __getInput (h, fromDialog, isTarget) {
1062
+ const attrs = isTarget === true ? { ...this.comboboxAttrs, ...this.qAttrs } : void 0
1063
+
1060
1064
  const options = {
1061
1065
  ref: isTarget === true ? 'target' : void 0,
1062
1066
  key: 'i_t',
@@ -1067,15 +1071,14 @@ export default Vue.extend({
1067
1071
  attrs: {
1068
1072
  // required for Android in order to show ENTER key when in form
1069
1073
  type: 'search',
1070
- ...this.qAttrs,
1074
+ ...attrs,
1071
1075
  id: isTarget === true ? this.targetUid : void 0,
1072
1076
  maxlength: this.maxlength, // this is converted to prop by QField
1073
1077
  tabindex: this.tabindex,
1074
1078
  autocomplete: this.autocomplete,
1075
1079
  'data-autofocus': fromDialog === true ? false : this.autofocus,
1076
1080
  disabled: this.disable === true,
1077
- readonly: this.readonly === true,
1078
- ...this.comboboxAttrs
1081
+ readonly: this.readonly === true
1079
1082
  },
1080
1083
  on: this.inputControlEvents
1081
1084
  }
@@ -73,8 +73,8 @@ export default Vue.extend({
73
73
 
74
74
  this.timer = setTimeout(() => {
75
75
  el.style.height = `${el.scrollHeight}px`
76
- this.animListener = ev => {
77
- if (Object(ev) !== ev || ev.target === el) {
76
+ this.animListener = evt => {
77
+ if (Object(evt) !== evt || evt.target === el) {
78
78
  this.__end(el, 'show')
79
79
  }
80
80
  }
@@ -99,8 +99,8 @@ export default Vue.extend({
99
99
 
100
100
  this.timer = setTimeout(() => {
101
101
  el.style.height = 0
102
- this.animListener = ev => {
103
- if (Object(ev) !== ev || ev.target === el) {
102
+ this.animListener = evt => {
103
+ if (Object(evt) !== evt || evt.target === el) {
104
104
  this.__end(el, 'hide')
105
105
  }
106
106
  }
@@ -5,7 +5,7 @@ import FormMixin from '../../mixins/form.js'
5
5
 
6
6
  import { between } from '../../utils/format.js'
7
7
  import { position } from '../../utils/event.js'
8
- import { isNumber } from '../../utils/is.js'
8
+ import { isNumber, isObject } from '../../utils/is.js'
9
9
 
10
10
  const markerPrefixClass = 'q-slider__marker-labels'
11
11
  const defaultMarkerConvertFn = v => ({ value: v })
@@ -414,7 +414,7 @@ export const SliderMixin = {
414
414
  if (typeof def === 'function') {
415
415
  return this.markerTicks.map(value => {
416
416
  const item = def(value)
417
- return Object(item) === item ? { ...item, value } : { value, label: item }
417
+ return isObject(item) === true ? { ...item, value } : { value, label: item }
418
418
  })
419
419
  }
420
420
 
@@ -422,14 +422,14 @@ export const SliderMixin = {
422
422
 
423
423
  if (Array.isArray(def) === true) {
424
424
  return def
425
- .map(item => (Object(item) === item ? item : { value: item }))
425
+ .map(item => (isObject(item) === true ? item : { value: item }))
426
426
  .filter(filterFn)
427
427
  }
428
428
 
429
429
  return Object.keys(def).map(key => {
430
430
  const item = def[ key ]
431
431
  const value = Number(key)
432
- return Object(item) === item ? { ...item, value } : { value, label: item }
432
+ return isObject(item) === true ? { ...item, value } : { value, label: item }
433
433
  }).filter(filterFn)
434
434
  },
435
435
 
@@ -29,7 +29,7 @@
29
29
  "inner-max": {
30
30
  "type": "Number",
31
31
  "desc": "Inner maximum value of the model; Use in case you need the model value to be inside of the track's min-max values; Needs to be lower or equal to 'max' prop; Defaults to 'max' prop",
32
- "examples": [ ":max-value=\"100\"" ],
32
+ "examples": [ ":inner-max=\"100\"" ],
33
33
  "category": "model",
34
34
  "addedIn": "v1.17"
35
35
  },
@@ -49,6 +49,7 @@
49
49
 
50
50
  "done-icon": {
51
51
  "extends": "icon",
52
+ "desc": "Icon name following Quasar convention; If 'none' (String) is used as value, then it will defer to prefix or the regular icon for this state; Make sure you have the icon library installed unless you are using 'img:' prefix",
52
53
  "category": "header"
53
54
  },
54
55
 
@@ -59,6 +60,7 @@
59
60
 
60
61
  "active-icon": {
61
62
  "extends": "icon",
63
+ "desc": "Icon name following Quasar convention; If 'none' (String) is used as value, then it will defer to prefix or the regular icon for this state; Make sure you have the icon library installed unless you are using 'img:' prefix",
62
64
  "category": "header"
63
65
  },
64
66
 
@@ -69,6 +71,7 @@
69
71
 
70
72
  "error-icon": {
71
73
  "extends": "icon",
74
+ "desc": "Icon name following Quasar convention; If 'none' (String) is used as value, then it will defer to prefix or the regular icon for this state; Make sure you have the icon library installed unless you are using 'img:' prefix",
72
75
  "category": "header"
73
76
  },
74
77
 
@@ -58,6 +58,7 @@
58
58
 
59
59
  "done-icon": {
60
60
  "extends": "icon",
61
+ "desc": "Icon name following Quasar convention; If 'none' (String) is used as value, then it will defer to prefix or the regular icon for this state; Make sure you have the icon library installed unless you are using 'img:' prefix",
61
62
  "category": "header"
62
63
  },
63
64
 
@@ -68,6 +69,7 @@
68
69
 
69
70
  "active-icon": {
70
71
  "extends": "icon",
72
+ "desc": "Icon name following Quasar convention; If 'none' (String) is used as value, then it will defer to prefix or the regular icon for this state; Make sure you have the icon library installed unless you are using 'img:' prefix",
71
73
  "category": "header"
72
74
  },
73
75
 
@@ -78,6 +80,7 @@
78
80
 
79
81
  "error-icon": {
80
82
  "extends": "icon",
83
+ "desc": "Icon name following Quasar convention; If 'none' (String) is used as value, then it will defer to prefix or the regular icon for this state; Make sure you have the icon library installed unless you are using 'img:' prefix",
81
84
  "category": "header"
82
85
  },
83
86