quasar 2.1.8 → 2.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/dist/api/QCarousel.json +19 -5
  2. package/dist/api/QColor.json +6 -0
  3. package/dist/api/QInnerLoading.json +32 -0
  4. package/dist/api/QOptionGroup.json +58 -1
  5. package/dist/api/QRange.json +10 -3
  6. package/dist/api/QSeparator.json +1 -1
  7. package/dist/api/QSkeleton.json +14 -0
  8. package/dist/api/QSlider.json +10 -3
  9. package/dist/api/QStepper.json +16 -2
  10. package/dist/api/QTabPanels.json +16 -2
  11. package/dist/api/QTable.json +5 -0
  12. package/dist/icon-set/bootstrap-icons.umd.prod.js +1 -1
  13. package/dist/icon-set/eva-icons.umd.prod.js +1 -1
  14. package/dist/icon-set/fontawesome-v5-pro.umd.prod.js +1 -1
  15. package/dist/icon-set/fontawesome-v5.umd.prod.js +1 -1
  16. package/dist/icon-set/ionicons-v4.umd.prod.js +1 -1
  17. package/dist/icon-set/line-awesome.umd.prod.js +1 -1
  18. package/dist/icon-set/material-icons-outlined.umd.prod.js +1 -1
  19. package/dist/icon-set/material-icons-round.umd.prod.js +1 -1
  20. package/dist/icon-set/material-icons-sharp.umd.prod.js +1 -1
  21. package/dist/icon-set/material-icons.umd.prod.js +1 -1
  22. package/dist/icon-set/mdi-v3.umd.prod.js +1 -1
  23. package/dist/icon-set/mdi-v4.umd.prod.js +1 -1
  24. package/dist/icon-set/mdi-v5.umd.prod.js +1 -1
  25. package/dist/icon-set/mdi-v6.umd.prod.js +1 -1
  26. package/dist/icon-set/svg-bootstrap-icons.umd.prod.js +1 -1
  27. package/dist/icon-set/svg-eva-icons.umd.prod.js +1 -1
  28. package/dist/icon-set/svg-fontawesome-v5.umd.prod.js +1 -1
  29. package/dist/icon-set/svg-ionicons-v4.umd.prod.js +1 -1
  30. package/dist/icon-set/svg-ionicons-v5.umd.prod.js +1 -1
  31. package/dist/icon-set/svg-line-awesome.umd.prod.js +1 -1
  32. package/dist/icon-set/svg-material-icons-outlined.umd.prod.js +1 -1
  33. package/dist/icon-set/svg-material-icons-round.umd.prod.js +1 -1
  34. package/dist/icon-set/svg-material-icons-sharp.umd.prod.js +1 -1
  35. package/dist/icon-set/svg-material-icons.umd.prod.js +1 -1
  36. package/dist/icon-set/svg-mdi-v4.umd.prod.js +1 -1
  37. package/dist/icon-set/svg-mdi-v5.umd.prod.js +1 -1
  38. package/dist/icon-set/svg-mdi-v6.umd.prod.js +1 -1
  39. package/dist/icon-set/svg-themify.umd.prod.js +1 -1
  40. package/dist/icon-set/themify.umd.prod.js +1 -1
  41. package/dist/lang/ar.umd.prod.js +1 -1
  42. package/dist/lang/az-Latn.umd.prod.js +1 -1
  43. package/dist/lang/bg.umd.prod.js +1 -1
  44. package/dist/lang/bn.umd.prod.js +1 -1
  45. package/dist/lang/ca.umd.prod.js +1 -1
  46. package/dist/lang/cs.umd.prod.js +1 -1
  47. package/dist/lang/da.umd.prod.js +1 -1
  48. package/dist/lang/de.umd.prod.js +1 -1
  49. package/dist/lang/el.umd.prod.js +1 -1
  50. package/dist/lang/en-GB.umd.prod.js +1 -1
  51. package/dist/lang/en-US.umd.prod.js +1 -1
  52. package/dist/lang/eo.umd.prod.js +1 -1
  53. package/dist/lang/es.umd.prod.js +1 -1
  54. package/dist/lang/et.umd.prod.js +1 -1
  55. package/dist/lang/fa-IR.umd.prod.js +1 -1
  56. package/dist/lang/fa.umd.prod.js +1 -1
  57. package/dist/lang/fi.umd.prod.js +1 -1
  58. package/dist/lang/fr.umd.prod.js +1 -1
  59. package/dist/lang/gn.umd.prod.js +1 -1
  60. package/dist/lang/he.umd.prod.js +1 -1
  61. package/dist/lang/hr.umd.prod.js +1 -1
  62. package/dist/lang/hu.umd.prod.js +1 -1
  63. package/dist/lang/id.umd.prod.js +1 -1
  64. package/dist/lang/is.umd.prod.js +1 -1
  65. package/dist/lang/it.umd.prod.js +1 -1
  66. package/dist/lang/ja.umd.prod.js +1 -1
  67. package/dist/lang/km.umd.prod.js +1 -1
  68. package/dist/lang/ko-KR.umd.prod.js +1 -1
  69. package/dist/lang/kur-CKB.umd.prod.js +1 -1
  70. package/dist/lang/lt.umd.prod.js +6 -0
  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 +2 -2
  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.css +24 -17
  97. package/dist/quasar.esm.prod.js +2 -2
  98. package/dist/quasar.prod.css +1 -1
  99. package/dist/quasar.rtl.css +29 -22
  100. package/dist/quasar.rtl.prod.css +1 -1
  101. package/dist/quasar.sass +24 -16
  102. package/dist/quasar.umd.js +374 -242
  103. package/dist/quasar.umd.prod.js +2 -2
  104. package/dist/ssr-directives/Morph.js +1 -1
  105. package/dist/types/index.d.ts +81 -12
  106. package/dist/vetur/quasar-attributes.json +39 -7
  107. package/dist/vetur/quasar-tags.json +9 -1
  108. package/dist/web-types/web-types.json +101 -15
  109. package/lang/index.json +4 -0
  110. package/lang/lt.js +103 -0
  111. package/lang/ug.js +42 -42
  112. package/package.json +1 -1
  113. package/src/components/btn/QBtn.js +17 -20
  114. package/src/components/carousel/QCarousel.js +8 -1
  115. package/src/components/carousel/QCarousel.json +9 -1
  116. package/src/components/color/QColor.js +73 -61
  117. package/src/components/color/QColor.json +7 -0
  118. package/src/components/color/QColor.sass +5 -1
  119. package/src/components/dialog/QDialog.js +6 -0
  120. package/src/components/drawer/QDrawer.js +3 -0
  121. package/src/components/inner-loading/QInnerLoading.js +31 -7
  122. package/src/components/inner-loading/QInnerLoading.json +29 -0
  123. package/src/components/inner-loading/QInnerLoading.sass +4 -0
  124. package/src/components/option-group/QOptionGroup.js +29 -19
  125. package/src/components/option-group/QOptionGroup.json +50 -1
  126. package/src/components/range/QRange.js +1 -1
  127. package/src/components/range/QRange.json +7 -3
  128. package/src/components/rating/QRating.js +59 -39
  129. package/src/components/rating/QRating.sass +8 -6
  130. package/src/components/select/QSelect.js +1 -1
  131. package/src/components/separator/QSeparator.json +1 -1
  132. package/src/components/skeleton/QSkeleton.js +15 -5
  133. package/src/components/skeleton/QSkeleton.json +9 -0
  134. package/src/components/skeleton/QSkeleton.sass +7 -6
  135. package/src/components/slider/QSlider.js +1 -1
  136. package/src/components/slider/QSlider.json +7 -3
  137. package/src/components/slider/use-slider.js +7 -2
  138. package/src/components/stepper/StepHeader.js +10 -10
  139. package/src/components/table/QTable.json +1 -0
  140. package/src/components/tabs/use-tab.js +11 -9
  141. package/src/components/time/QTime.js +0 -2
  142. package/src/composables/private/use-panel.js +13 -8
  143. package/src/composables/private/use-panel.json +11 -2
  144. package/src/css/core/transitions.sass +4 -4
  145. package/src/utils/date.js +93 -60
@@ -48,7 +48,7 @@ export default defineComponent({
48
48
 
49
49
  emits: [ 'update:modelValue' ],
50
50
 
51
- setup (props, { emit }) {
51
+ setup (props, { emit, slots }) {
52
52
  const { proxy: { $q } } = getCurrentInstance()
53
53
 
54
54
  const arrayModel = Array.isArray(props.modelValue)
@@ -92,23 +92,33 @@ export default defineComponent({
92
92
  return () => h('div', {
93
93
  class: classes.value,
94
94
  ...attrs.value
95
- }, props.options.map(opt => h('div', [
96
- h(component.value, {
97
- modelValue: props.modelValue,
98
- val: opt.value,
99
- name: opt.name === void 0 ? props.name : opt.name,
100
- disable: props.disable || opt.disable,
101
- label: opt.label,
102
- leftLabel: opt.leftLabel === void 0 ? props.leftLabel : opt.leftLabel,
103
- color: opt.color === void 0 ? props.color : opt.color,
104
- checkedIcon: opt.checkedIcon,
105
- uncheckedIcon: opt.uncheckedIcon,
106
- dark: opt.dark || isDark.value,
107
- size: opt.size === void 0 ? props.size : opt.size,
108
- dense: props.dense,
109
- keepColor: opt.keepColor === void 0 ? props.keepColor : opt.keepColor,
110
- 'onUpdate:modelValue': onUpdateModelValue
111
- })
112
- ])))
95
+ }, props.options.map((opt, i) => {
96
+ const child = slots[ 'label-' + i ] !== void 0
97
+ ? () => slots[ 'label-' + i ](opt)
98
+ : (
99
+ slots.label !== void 0
100
+ ? () => slots.label(opt)
101
+ : void 0
102
+ )
103
+
104
+ return h('div', [
105
+ h(component.value, {
106
+ modelValue: props.modelValue,
107
+ val: opt.value,
108
+ name: opt.name === void 0 ? props.name : opt.name,
109
+ disable: props.disable || opt.disable,
110
+ label: child === void 0 ? opt.label : null,
111
+ leftLabel: opt.leftLabel === void 0 ? props.leftLabel : opt.leftLabel,
112
+ color: opt.color === void 0 ? props.color : opt.color,
113
+ checkedIcon: opt.checkedIcon,
114
+ uncheckedIcon: opt.uncheckedIcon,
115
+ dark: opt.dark || isDark.value,
116
+ size: opt.size === void 0 ? props.size : opt.size,
117
+ dense: props.dense,
118
+ keepColor: opt.keepColor === void 0 ? props.keepColor : opt.keepColor,
119
+ 'onUpdate:modelValue': onUpdateModelValue
120
+ }, child)
121
+ ])
122
+ }))
113
123
  }
114
124
  })
@@ -14,7 +14,30 @@
14
14
 
15
15
  "options": {
16
16
  "type": "Array",
17
- "desc": "Array of objects with value and label props. The binary components will be created according to this array; Props from QToggle, QCheckbox or QRadio can also be added as key/value pairs to control the components singularly",
17
+ "desc": "Array of objects with value, label, and disable (optional) props. The binary components will be created according to this array; Props from QToggle, QCheckbox or QRadio can also be added as key/value pairs to control the components singularly",
18
+ "definition": {
19
+ "label": {
20
+ "type": "String",
21
+ "desc": "Label to display along the component",
22
+ "required": true,
23
+ "examples": [ "Option 1", "Option 2", "Option 3" ]
24
+ },
25
+ "value": {
26
+ "type": "Any",
27
+ "desc": "Value of the option that will be used by the component model",
28
+ "required": true,
29
+ "examples": [ "op1", "op2", "op3" ]
30
+ },
31
+ "disable": {
32
+ "type": "Boolean",
33
+ "desc": "If true, the option will be disabled"
34
+ },
35
+ "...props": {
36
+ "type": "Any",
37
+ "desc": "Any other props from QToggle, QCheckbox, or QRadio",
38
+ "examples": [ "val=\"car\"", ":true-value=\"trueValue\"", "checked-icon=\"visibility\"" ]
39
+ }
40
+ },
18
41
  "examples": [
19
42
  ":options=\"[ { label: 'Option 1', value: 'op1' }, { label: 'Option 2', value: 'op2' }, { label: 'Option 3', value: 'op3', disable: true } ]\""
20
43
  ],
@@ -72,6 +95,32 @@
72
95
  }
73
96
  },
74
97
 
98
+ "slots": {
99
+ "label": {
100
+ "desc": "Generic slot for all labels",
101
+ "scope": {
102
+ "opt": {
103
+ "type": "Object",
104
+ "desc": "The corresponding option entry from the 'options' prop",
105
+ "__exemption": [ "examples" ]
106
+ }
107
+ },
108
+ "addedIn": "v2.2"
109
+ },
110
+
111
+ "label-[name]": {
112
+ "desc": "Slot to define the specific label for the option at '[name]' where name is a 0-based index; Overrides the generic 'label' slot if used",
113
+ "scope": {
114
+ "...opt": {
115
+ "type": "Object",
116
+ "desc": "The corresponding option entry from the 'options' prop",
117
+ "__exemption": [ "examples" ]
118
+ }
119
+ },
120
+ "addedIn": "v2.2"
121
+ }
122
+ },
123
+
75
124
  "events": {
76
125
  "update:model-value": {
77
126
  "extends": "update:model-value"
@@ -488,7 +488,7 @@ export default defineComponent({
488
488
  })
489
489
  ]
490
490
 
491
- props.markers === true && track.push(
491
+ props.markers !== false && track.push(
492
492
  h('div', {
493
493
  class: `q-slider__track-markers q-slider__track-markers${ state.axis.value } absolute-full fit`,
494
494
  style: state.markerStyle.value
@@ -144,9 +144,13 @@
144
144
  },
145
145
 
146
146
  "markers": {
147
- "type": "Boolean",
148
- "desc": "Display markers on the track, one for each possible value for the model",
149
- "category": "content"
147
+ "type": [ "Boolean", "Number" ],
148
+ "desc": "Display markers on the track, one for each possible value for the model or using a custom step (when specifying a Number)",
149
+ "category": "content",
150
+ "examples": [
151
+ "markers",
152
+ ":markers=\"5\""
153
+ ]
150
154
  },
151
155
 
152
156
  "snap": {
@@ -4,6 +4,7 @@ import QIcon from '../icon/QIcon.js'
4
4
 
5
5
  import { stopAndPrevent } from '../../utils/event.js'
6
6
  import { between } from '../../utils/format.js'
7
+ import { hMergeSlot } from '../../utils/private/render.js'
7
8
 
8
9
  import useSize, { useSizeProps } from '../../composables/private/use-size.js'
9
10
  import { useFormProps, useFormAttrs, useFormInject } from '../../composables/private/use-form.js'
@@ -94,6 +95,51 @@ export default defineComponent({
94
95
  }
95
96
  })
96
97
 
98
+ const stars = computed(() => {
99
+ const
100
+ acc = [],
101
+ icons = iconData.value,
102
+ ceil = Math.ceil(props.modelValue)
103
+
104
+ const halfIndex = props.iconHalf === void 0 || ceil === props.modelValue
105
+ ? -1
106
+ : ceil
107
+
108
+ for (let i = 1; i <= props.max; i++) {
109
+ const
110
+ active = (mouseModel.value === 0 && props.modelValue >= i) || (mouseModel.value > 0 && mouseModel.value >= i),
111
+ half = halfIndex === i && mouseModel.value < i,
112
+ exSelected = mouseModel.value > 0 && (half === true ? ceil : props.modelValue) >= i && mouseModel.value < i,
113
+ color = half === true
114
+ ? (i <= icons.halfColorLen ? props.colorHalf[ i - 1 ] : icons.halfColor)
115
+ : (
116
+ icons.selColor !== void 0 && active === true
117
+ ? (i <= icons.selColorLen ? props.colorSelected[ i - 1 ] : icons.selColor)
118
+ : (i <= icons.colorLen ? props.color[ i - 1 ] : icons.color)
119
+ )
120
+
121
+ acc.push({
122
+ name: (
123
+ half === true
124
+ ? (i <= icons.halfIconLen ? props.iconHalf[ i - 1 ] : icons.halfIcon)
125
+ : (
126
+ icons.selIcon !== void 0 && (active === true || exSelected === true)
127
+ ? (i <= icons.selIconLen ? props.iconSelected[ i - 1 ] : icons.selIcon)
128
+ : (i <= icons.iconLen ? props.icon[ i - 1 ] : icons.icon)
129
+ )
130
+ ) || $q.iconSet.rating.icon,
131
+
132
+ classes: 'q-rating__icon'
133
+ + (active === true || half === true ? ' q-rating__icon--active' : '')
134
+ + (exSelected === true ? ' q-rating__icon--exselected' : '')
135
+ + (mouseModel.value === i ? ' q-rating__icon--hovered' : '')
136
+ + (color !== void 0 ? ` text-${ color }` : '')
137
+ })
138
+ }
139
+
140
+ return acc
141
+ })
142
+
97
143
  const attributes = computed(() => {
98
144
  if (props.disable === true) {
99
145
  return { 'aria-disabled': 'true' }
@@ -103,6 +149,8 @@ export default defineComponent({
103
149
  }
104
150
  })
105
151
 
152
+ const tabindex = computed(() => (editable.value === true ? 0 : null))
153
+
106
154
  function set (value) {
107
155
  if (editable.value === true) {
108
156
  const
@@ -150,57 +198,29 @@ export default defineComponent({
150
198
  })
151
199
 
152
200
  return () => {
153
- const
154
- child = [],
155
- tabindex = editable.value === true ? 0 : null,
156
- icons = iconData.value,
157
- ceil = Math.ceil(props.modelValue)
201
+ const child = []
158
202
 
159
- const halfIndex = props.iconHalf === void 0 || ceil === props.modelValue
160
- ? -1
161
- : ceil
162
-
163
- for (let i = 1; i <= props.max; i++) {
164
- const
165
- active = (mouseModel.value === 0 && props.modelValue >= i) || (mouseModel.value > 0 && mouseModel.value >= i),
166
- half = halfIndex === i && mouseModel.value < i,
167
- exSelected = mouseModel.value > 0 && (half === true ? ceil : props.modelValue) >= i && mouseModel.value < i,
168
- name = half === true
169
- ? (i <= icons.halfIconLen ? props.iconHalf[ i - 1 ] : icons.halfIcon)
170
- : (
171
- icons.selIcon !== void 0 && (active === true || exSelected === true)
172
- ? (i <= icons.selIconLen ? props.iconSelected[ i - 1 ] : icons.selIcon)
173
- : (i <= icons.iconLen ? props.icon[ i - 1 ] : icons.icon)
174
- ),
175
- color = half === true
176
- ? (i <= icons.halfColorLen ? props.colorHalf[ i - 1 ] : icons.halfColor)
177
- : (
178
- icons.selColor !== void 0 && active === true
179
- ? (i <= icons.selColorLen ? props.colorSelected[ i - 1 ] : icons.selColor)
180
- : (i <= icons.colorLen ? props.color[ i - 1 ] : icons.color)
181
- ),
182
- classes = 'q-rating__icon'
183
- + (active === true || half === true ? ' q-rating__icon--active' : '')
184
- + (exSelected === true ? ' q-rating__icon--exselected' : '')
185
- + (mouseModel.value === i ? ' q-rating__icon--hovered' : '')
186
- + (color !== void 0 ? ` text-${ color }` : '')
203
+ stars.value.forEach(({ classes, name }, index) => {
204
+ const i = index + 1
187
205
 
188
206
  child.push(
189
- h(QIcon, {
207
+ h('div', {
190
208
  key: i,
191
209
  ref: vm => { iconRefs[ `rt${ i }` ] = vm },
192
- class: classes,
193
- name: name || $q.iconSet.rating.icon,
194
- tabindex,
210
+ class: 'q-rating__icon-container flex flex-center',
211
+ tabindex: tabindex.value,
195
212
  onClick () { set(i) },
196
213
  onMouseover () { setHoverValue(i) },
197
214
  onMouseout: resetMouseModel,
198
215
  onFocus () { setHoverValue(i) },
199
216
  onBlur: resetMouseModel,
200
217
  onKeyup (e) { onKeyup(e, i) }
201
- }, slots[ `tip-${ i }` ])
218
+ }, hMergeSlot(
219
+ slots[ `tip-${ i }` ],
220
+ [ h(QIcon, { class: classes, name }) ]
221
+ ))
202
222
  )
203
- }
223
+ })
204
224
 
205
225
  if (props.name !== void 0 && props.disable !== true) {
206
226
  injectFormInput(child, 'push')
@@ -2,6 +2,13 @@
2
2
  color: $rating-grade-color
3
3
  vertical-align: middle
4
4
 
5
+ &__icon-container
6
+ height: 1em
7
+ outline: 0
8
+
9
+ & + &
10
+ margin-left: 2px
11
+
5
12
  &__icon
6
13
  color: currentColor
7
14
  text-shadow: $rating-shadow
@@ -17,13 +24,8 @@
17
24
  &--exselected
18
25
  opacity: .7
19
26
 
20
- & + &
21
- margin-left: 2px
22
-
23
27
  &--no-dimming .q-rating__icon
24
28
  opacity: 1
25
29
 
26
- &--editable .q-icon
30
+ &--editable .q-rating__icon-container
27
31
  cursor: pointer
28
- &--non-editable span, .q-icon
29
- outline: 0
@@ -268,7 +268,7 @@ 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
+ tabindex: props.tabindex,
272
272
  role: 'combobox',
273
273
  'aria-label': props.label,
274
274
  'aria-autocomplete': props.useInput === true ? 'list' : 'none',
@@ -20,7 +20,7 @@
20
20
 
21
21
  "inset": {
22
22
  "type": [ "Boolean", "String" ],
23
- "desc": "if set to true, the left and right margins will be set to 16px. If set to item, the left and right margins will be set to 72px. If set to item-thumbnail, the left margin is set to 116px and right margin is set to 0px",
23
+ "desc": "If set to Boolean true, the left and right margins will be set to 16px. If set to 'item' then it will match a QItem's design. If set to 'item-thumbnail' then it will match the design of a QItem with a thumbnail on the left side",
24
24
  "examples": [ "item", "item-thumbnail" ],
25
25
  "category": "content"
26
26
  },
@@ -38,6 +38,10 @@ export default defineComponent({
38
38
  validator: v => skeletonAnimations.includes(v),
39
39
  default: 'wave'
40
40
  },
41
+ animationSpeed: {
42
+ type: [ String, Number ],
43
+ default: 1500
44
+ },
41
45
 
42
46
  square: Boolean,
43
47
  bordered: Boolean,
@@ -51,11 +55,17 @@ export default defineComponent({
51
55
  const vm = getCurrentInstance()
52
56
  const isDark = useDark(props, vm.proxy.$q)
53
57
 
54
- const style = computed(() => (
55
- props.size !== void 0
56
- ? { width: props.size, height: props.size }
57
- : { width: props.width, height: props.height }
58
- ))
58
+ const style = computed(() => {
59
+ const size = props.size !== void 0
60
+ ? [ props.size, props.size ]
61
+ : [ props.width, props.height ]
62
+
63
+ return {
64
+ '--q-skeleton-speed': `${ props.animationSpeed }ms`,
65
+ width: size[ 0 ],
66
+ height: size[ 1 ]
67
+ }
68
+ })
59
69
 
60
70
  const classes = computed(() =>
61
71
  `q-skeleton q-skeleton--${ isDark.value === true ? 'dark' : 'light' } q-skeleton--type-${ props.type }`
@@ -32,6 +32,15 @@
32
32
  "category": "style"
33
33
  },
34
34
 
35
+ "animation-speed": {
36
+ "type": [ "String", "Number" ],
37
+ "desc": "Animation speed (in milliseconds, without unit)",
38
+ "default": 300,
39
+ "examples": [ 500, "1200" ],
40
+ "category": "style",
41
+ "addedIn": "v2.2"
42
+ },
43
+
35
44
  "square": {
36
45
  "extends": "square"
37
46
  },
@@ -1,4 +1,5 @@
1
1
  .q-skeleton
2
+ --q-skeleton-speed: 1500ms
2
3
  background: $separator-color
3
4
  border-radius: $generic-border-radius
4
5
 
@@ -58,14 +59,14 @@
58
59
  border-radius: 0
59
60
 
60
61
  &--anim-fade
61
- animation: q-skeleton--fade 1.5s linear .5s infinite
62
+ animation: q-skeleton--fade var(--q-skeleton-speed) linear .5s infinite
62
63
 
63
64
  &--anim-pulse
64
- animation: q-skeleton--pulse 1.5s ease-in-out .5s infinite
65
+ animation: q-skeleton--pulse var(--q-skeleton-speed) ease-in-out .5s infinite
65
66
  &--anim-pulse-x
66
- animation: q-skeleton--pulse-x 1.5s ease-in-out .5s infinite
67
+ animation: q-skeleton--pulse-x var(--q-skeleton-speed) ease-in-out .5s infinite
67
68
  &--anim-pulse-y
68
- animation: q-skeleton--pulse-y 1.5s ease-in-out .5s infinite
69
+ animation: q-skeleton--pulse-y var(--q-skeleton-speed) ease-in-out .5s infinite
69
70
 
70
71
  &--anim-wave,
71
72
  &--anim-blink,
@@ -84,10 +85,10 @@
84
85
 
85
86
  &--anim-blink:after
86
87
  background: rgba(255,255,255,.7)
87
- animation: q-skeleton--fade 1.5s linear .5s infinite
88
+ animation: q-skeleton--fade var(--q-skeleton-speed) linear .5s infinite
88
89
  &--anim-wave:after
89
90
  background: linear-gradient(90deg, rgba(255,255,255,0), rgba(255,255,255,.5), rgba(255,255,255,0))
90
- animation: q-skeleton--wave 1.5s linear .5s infinite
91
+ animation: q-skeleton--wave var(--q-skeleton-speed) linear .5s infinite
91
92
 
92
93
  &--dark
93
94
  background: rgba(255, 255, 255, 0.05)
@@ -206,7 +206,7 @@ export default defineComponent({
206
206
  })
207
207
  ]
208
208
 
209
- props.markers === true && track.push(
209
+ props.markers !== false && track.push(
210
210
  h('div', {
211
211
  class: `q-slider__track-markers q-slider__track-markers${ state.axis.value } absolute-full fit`,
212
212
  style: state.markerStyle.value
@@ -83,9 +83,13 @@
83
83
  },
84
84
 
85
85
  "markers": {
86
- "type": "Boolean",
87
- "desc": "Display markers on the track, one for each possible value for the model",
88
- "category": "content"
86
+ "type": [ "Boolean", "Number" ],
87
+ "desc": "Display markers on the track, one for each possible value for the model or using a custom step (when specifying a Number)",
88
+ "category": "content",
89
+ "examples": [
90
+ "markers",
91
+ ":markers=\"5\""
92
+ ]
89
93
  },
90
94
 
91
95
  "snap": {
@@ -6,6 +6,7 @@ import useDark, { useDarkProps } from '../../composables/private/use-dark.js'
6
6
 
7
7
  import { between } from '../../utils/format.js'
8
8
  import { position } from '../../utils/event.js'
9
+ import { isNumber } from '../../utils/private/is.js'
9
10
 
10
11
  // PGDOWN, LEFT, DOWN, PGUP, RIGHT, UP
11
12
  export const keyCodes = [ 34, 37, 40, 33, 39, 38 ]
@@ -60,7 +61,7 @@ export const useSliderProps = {
60
61
 
61
62
  label: Boolean,
62
63
  labelAlways: Boolean,
63
- markers: Boolean,
64
+ markers: [ Boolean, Number ],
64
65
  snap: Boolean,
65
66
 
66
67
  vertical: Boolean,
@@ -113,9 +114,13 @@ export default function ({ updateValue, updatePosition, getDragging }) {
113
114
  const step = computed(() => (props.step === 0 ? 1 : props.step))
114
115
  const minMaxDiff = computed(() => props.max - props.min)
115
116
 
117
+ const markerStep = computed(() => (
118
+ isNumber(props.markers) === true ? props.markers : step.value)
119
+ )
120
+
116
121
  const markerStyle = computed(() => {
117
122
  if (minMaxDiff.value !== 0) {
118
- const size = 100 * step.value / minMaxDiff.value
123
+ const size = 100 * markerStep.value / minMaxDiff.value
119
124
 
120
125
  return {
121
126
  backgroundSize: props.vertical === true
@@ -1,10 +1,8 @@
1
- import { h, defineComponent, ref, computed, getCurrentInstance } from 'vue'
1
+ import { h, defineComponent, ref, computed, withDirectives, getCurrentInstance } from 'vue'
2
2
 
3
3
  import QIcon from '../icon/QIcon.js'
4
4
  import Ripple from '../../directives/Ripple.js'
5
5
 
6
- import { hDir } from '../../utils/private/render.js'
7
-
8
6
  export default defineComponent({
9
7
  name: 'StepHeader',
10
8
 
@@ -97,6 +95,12 @@ export default defineComponent({
97
95
  + (isDisable.value === true ? ' q-stepper__tab--disabled' : '')
98
96
  })
99
97
 
98
+ const ripple = computed(() => (
99
+ props.stepper.headerNav !== true
100
+ ? false
101
+ : headerNav.value
102
+ ))
103
+
100
104
  function onActivate () {
101
105
  blurRef.value !== null && blurRef.value.focus()
102
106
  isActive.value === false && props.goToPanel(props.step.name)
@@ -152,13 +156,9 @@ export default defineComponent({
152
156
  )
153
157
  }
154
158
 
155
- return hDir(
156
- 'div',
157
- data,
158
- child,
159
- 'head',
160
- props.stepper.headerNav === true && headerNav.value !== false,
161
- () => [ [ Ripple, headerNav.value ] ]
159
+ return withDirectives(
160
+ h('div', data, child),
161
+ [ [ Ripple, ripple.value ] ]
162
162
  )
163
163
  }
164
164
  }
@@ -156,6 +156,7 @@
156
156
  "align": {
157
157
  "type": "String",
158
158
  "desc": "Horizontal alignment of cells in this column",
159
+ "values": [ "left", "right", "center" ],
159
160
  "default": "right",
160
161
  "examples": [ "left", "right", "center" ]
161
162
  },
@@ -1,10 +1,10 @@
1
- import { h, ref, computed, inject, onBeforeUnmount, onMounted } from 'vue'
1
+ import { h, ref, computed, inject, onBeforeUnmount, onMounted, withDirectives } from 'vue'
2
2
 
3
3
  import QIcon from '../icon/QIcon.js'
4
4
 
5
5
  import Ripple from '../../directives/Ripple.js'
6
6
 
7
- import { hMergeSlot, hDir } from '../../utils/private/render.js'
7
+ import { hMergeSlot } from '../../utils/private/render.js'
8
8
  import { isKeyCode } from '../../utils/private/key-composition.js'
9
9
  import { tabsKey } from '../../utils/private/symbols.js'
10
10
 
@@ -46,6 +46,12 @@ export default function (props, slots, emit, routerProps) {
46
46
  const rootRef = ref(null)
47
47
  const tabIndicatorRef = ref(null)
48
48
 
49
+ const ripple = computed(() => (
50
+ props.disable === true
51
+ ? false
52
+ : props.ripple
53
+ ))
54
+
49
55
  const isActive = computed(() => $tabs.currentModel.value === props.name)
50
56
 
51
57
  const classes = computed(() =>
@@ -202,13 +208,9 @@ export default function (props, slots, emit, routerProps) {
202
208
  ...customData
203
209
  }
204
210
 
205
- return hDir(
206
- tag,
207
- data,
208
- getContent(),
209
- 'main',
210
- props.ripple !== false && props.disable === false,
211
- () => [ [ Ripple, props.ripple ] ]
211
+ return withDirectives(
212
+ h(tag, data, getContent()),
213
+ [ [ Ripple, ripple.value ] ]
212
214
  )
213
215
  }
214
216
 
@@ -288,8 +288,6 @@ export default defineComponent({
288
288
  defaultDateModel.value
289
289
  )
290
290
 
291
- console.log({ ...model })
292
-
293
291
  if (
294
292
  model.dateHash !== innerModel.value.dateHash
295
293
  || model.timeHash !== innerModel.value.timeHash
@@ -33,6 +33,10 @@ export const usePanelProps = {
33
33
 
34
34
  transitionPrev: String,
35
35
  transitionNext: String,
36
+ transitionDuration: {
37
+ type: [ String, Number ],
38
+ default: 300
39
+ },
36
40
 
37
41
  keepAlive: Boolean,
38
42
  keepAliveInclude: [ String, Array, RegExp ],
@@ -78,6 +82,10 @@ export default function () {
78
82
  props.transitionNext || `slide-${ props.vertical === true ? 'up' : 'left' }`
79
83
  )
80
84
 
85
+ const transitionStyle = computed(
86
+ () => `--q-transition-duration: ${ props.transitionDuration }ms`
87
+ )
88
+
81
89
  const contentKey = computed(() => (
82
90
  typeof props.modelValue === 'string' || typeof props.modelValue === 'number'
83
91
  ? props.modelValue
@@ -197,7 +205,7 @@ export default function () {
197
205
  }
198
206
 
199
207
  function getPanelContentChild () {
200
- const panel = isValidPanelName(props.modelValue)
208
+ const panel = isValidPanelName(props.modelValue) === true
201
209
  && updatePanelIndex()
202
210
  && panels[ panelIndex.value ]
203
211
 
@@ -208,7 +216,7 @@ export default function () {
208
216
  needsUniqueKeepAliveWrapper.value === true
209
217
  ? getCacheWithFn(contentKey.value, () => ({ ...PanelWrapper, name: contentKey.value }))
210
218
  : PanelWrapper,
211
- { key: contentKey.value },
219
+ { key: contentKey.value, style: transitionStyle.value },
212
220
  () => panel
213
221
  )
214
222
  ])
@@ -216,6 +224,7 @@ export default function () {
216
224
  : [
217
225
  h('div', {
218
226
  class: 'q-panel scroll',
227
+ style: transitionStyle.value,
219
228
  key: contentKey.value,
220
229
  role: 'tabpanel'
221
230
  }, [ panel ])
@@ -228,11 +237,7 @@ export default function () {
228
237
  }
229
238
 
230
239
  return props.animated === true
231
- ? [
232
- h(Transition, {
233
- name: panelTransition.value
234
- }, getPanelContentChild)
235
- ]
240
+ ? [ h(Transition, { name: panelTransition.value }, getPanelContentChild) ]
236
241
  : getPanelContentChild()
237
242
  }
238
243
 
@@ -242,7 +247,7 @@ export default function () {
242
247
  ).filter(
243
248
  panel => panel.props !== null
244
249
  && panel.props.slot === void 0
245
- && isValidPanelName(panel.props.name)
250
+ && isValidPanelName(panel.props.name) === true
246
251
  )
247
252
 
248
253
  return panels.length