quasar 2.9.1 → 2.10.0

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 (171) hide show
  1. package/dist/api/QBreadcrumbsEl.json +0 -14
  2. package/dist/api/QBtnDropdown.json +36 -0
  3. package/dist/api/QPagination.json +134 -102
  4. package/dist/api/QTabs.json +1 -1
  5. package/dist/api/QTree.json +6 -0
  6. package/dist/api/TouchPan.json +0 -4
  7. package/dist/icon-set/bootstrap-icons.umd.prod.js +1 -1
  8. package/dist/icon-set/eva-icons.umd.prod.js +1 -1
  9. package/dist/icon-set/fontawesome-v5-pro.umd.prod.js +1 -1
  10. package/dist/icon-set/fontawesome-v5.umd.prod.js +1 -1
  11. package/dist/icon-set/fontawesome-v6-pro.umd.prod.js +1 -1
  12. package/dist/icon-set/fontawesome-v6.umd.prod.js +1 -1
  13. package/dist/icon-set/ionicons-v4.umd.prod.js +1 -1
  14. package/dist/icon-set/line-awesome.umd.prod.js +1 -1
  15. package/dist/icon-set/material-icons-outlined.umd.prod.js +1 -1
  16. package/dist/icon-set/material-icons-round.umd.prod.js +1 -1
  17. package/dist/icon-set/material-icons-sharp.umd.prod.js +1 -1
  18. package/dist/icon-set/material-icons.umd.prod.js +1 -1
  19. package/dist/icon-set/material-symbols-outlined.umd.prod.js +1 -1
  20. package/dist/icon-set/material-symbols-rounded.umd.prod.js +1 -1
  21. package/dist/icon-set/material-symbols-sharp.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-fontawesome-v6.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-ionicons-v6.umd.prod.js +1 -1
  33. package/dist/icon-set/svg-line-awesome.umd.prod.js +1 -1
  34. package/dist/icon-set/svg-material-icons-outlined.umd.prod.js +1 -1
  35. package/dist/icon-set/svg-material-icons-round.umd.prod.js +1 -1
  36. package/dist/icon-set/svg-material-icons-sharp.umd.prod.js +1 -1
  37. package/dist/icon-set/svg-material-icons.umd.prod.js +1 -1
  38. package/dist/icon-set/svg-material-symbols-outlined.umd.prod.js +1 -1
  39. package/dist/icon-set/svg-material-symbols-rounded.umd.prod.js +1 -1
  40. package/dist/icon-set/svg-material-symbols-sharp.umd.prod.js +1 -1
  41. package/dist/icon-set/svg-mdi-v6.umd.prod.js +1 -1
  42. package/dist/icon-set/svg-themify.umd.prod.js +1 -1
  43. package/dist/icon-set/themify.umd.prod.js +1 -1
  44. package/dist/lang/ar-TN.umd.prod.js +1 -1
  45. package/dist/lang/ar.umd.prod.js +1 -1
  46. package/dist/lang/az-Latn.umd.prod.js +1 -1
  47. package/dist/lang/bg.umd.prod.js +1 -1
  48. package/dist/lang/bn.umd.prod.js +1 -1
  49. package/dist/lang/ca.umd.prod.js +1 -1
  50. package/dist/lang/cs.umd.prod.js +1 -1
  51. package/dist/lang/da.umd.prod.js +1 -1
  52. package/dist/lang/de.umd.prod.js +1 -1
  53. package/dist/lang/el.umd.prod.js +1 -1
  54. package/dist/lang/en-GB.umd.prod.js +1 -1
  55. package/dist/lang/en-US.umd.prod.js +1 -1
  56. package/dist/lang/eo.umd.prod.js +1 -1
  57. package/dist/lang/es.umd.prod.js +1 -1
  58. package/dist/lang/et.umd.prod.js +1 -1
  59. package/dist/lang/eu.umd.prod.js +1 -1
  60. package/dist/lang/fa-IR.umd.prod.js +1 -1
  61. package/dist/lang/fa.umd.prod.js +1 -1
  62. package/dist/lang/fi.umd.prod.js +1 -1
  63. package/dist/lang/fr.umd.prod.js +1 -1
  64. package/dist/lang/gn.umd.prod.js +1 -1
  65. package/dist/lang/he.umd.prod.js +1 -1
  66. package/dist/lang/hr.umd.prod.js +1 -1
  67. package/dist/lang/hu.umd.prod.js +1 -1
  68. package/dist/lang/id.umd.prod.js +1 -1
  69. package/dist/lang/is.umd.prod.js +1 -1
  70. package/dist/lang/it.umd.prod.js +1 -1
  71. package/dist/lang/ja.umd.prod.js +1 -1
  72. package/dist/lang/km.umd.prod.js +1 -1
  73. package/dist/lang/ko-KR.umd.prod.js +1 -1
  74. package/dist/lang/kur-CKB.umd.prod.js +1 -1
  75. package/dist/lang/kz.umd.prod.js +1 -1
  76. package/dist/lang/lt.umd.prod.js +1 -1
  77. package/dist/lang/lu.umd.prod.js +1 -1
  78. package/dist/lang/lv.umd.prod.js +1 -1
  79. package/dist/lang/ml.umd.prod.js +1 -1
  80. package/dist/lang/mm.umd.prod.js +1 -1
  81. package/dist/lang/ms.umd.prod.js +1 -1
  82. package/dist/lang/my.umd.prod.js +1 -1
  83. package/dist/lang/nb-NO.umd.prod.js +1 -1
  84. package/dist/lang/nl.umd.prod.js +1 -1
  85. package/dist/lang/pl.umd.prod.js +1 -1
  86. package/dist/lang/pt-BR.umd.prod.js +1 -1
  87. package/dist/lang/pt.umd.prod.js +1 -1
  88. package/dist/lang/ro.umd.prod.js +1 -1
  89. package/dist/lang/ru.umd.prod.js +1 -1
  90. package/dist/lang/sk.umd.prod.js +1 -1
  91. package/dist/lang/sl.umd.prod.js +1 -1
  92. package/dist/lang/sm.umd.prod.js +1 -1
  93. package/dist/lang/sr-CYR.umd.prod.js +1 -1
  94. package/dist/lang/sr.umd.prod.js +1 -1
  95. package/dist/lang/sv.umd.prod.js +1 -1
  96. package/dist/lang/ta.umd.prod.js +1 -1
  97. package/dist/lang/th.umd.prod.js +1 -1
  98. package/dist/lang/tr.umd.prod.js +1 -1
  99. package/dist/lang/ug.umd.prod.js +1 -1
  100. package/dist/lang/uk.umd.prod.js +1 -1
  101. package/dist/lang/uz-Cyrl.umd.prod.js +1 -1
  102. package/dist/lang/uz-Latn.umd.prod.js +1 -1
  103. package/dist/lang/vi.umd.prod.js +1 -1
  104. package/dist/lang/zh-CN.umd.prod.js +1 -1
  105. package/dist/lang/zh-TW.umd.prod.js +1 -1
  106. package/dist/quasar.cjs.prod.js +2 -2
  107. package/dist/quasar.css +10 -0
  108. package/dist/quasar.esm.js +554 -349
  109. package/dist/quasar.esm.prod.js +2 -2
  110. package/dist/quasar.prod.css +1 -1
  111. package/dist/quasar.rtl.css +26 -0
  112. package/dist/quasar.rtl.prod.css +1 -1
  113. package/dist/quasar.sass +11 -1
  114. package/dist/quasar.umd.js +554 -349
  115. package/dist/quasar.umd.prod.js +2 -2
  116. package/dist/transforms/auto-import.json +7 -3
  117. package/dist/transforms/import-map.json +2 -0
  118. package/dist/types/index.d.ts +70 -51
  119. package/dist/vetur/quasar-attributes.json +65 -49
  120. package/dist/vetur/quasar-tags.json +17 -13
  121. package/dist/web-types/web-types.json +131 -97
  122. package/package.json +1 -1
  123. package/src/components/badge/QBadge.js +1 -1
  124. package/src/components/badge/__tests__/QBadge.spec.js +98 -23
  125. package/src/components/breadcrumbs/QBreadcrumbsEl.json +0 -4
  126. package/src/components/breadcrumbs/__tests__/BasicBreadcrumbs.vue +7 -0
  127. package/src/components/breadcrumbs/__tests__/BreadcrumbWithSeparatorSlot.vue +11 -0
  128. package/src/components/breadcrumbs/__tests__/QBreadcrumbs.spec.js +112 -0
  129. package/src/components/breadcrumbs/__tests__/QBreadcrumbsEl.spec.js +87 -0
  130. package/src/components/btn/use-btn.js +24 -14
  131. package/src/components/btn-dropdown/QBtnDropdown.js +39 -16
  132. package/src/components/btn-dropdown/QBtnDropdown.json +1 -1
  133. package/src/components/btn-toggle/QBtnToggle.js +14 -14
  134. package/src/components/checkbox/use-checkbox.js +1 -1
  135. package/src/components/chip/QChip.js +14 -11
  136. package/src/components/dialog/QDialog.js +2 -1
  137. package/src/components/dialog-bottom-sheet/BottomSheet.js +6 -2
  138. package/src/components/drawer/QDrawer.js +5 -3
  139. package/src/components/footer/QFooter.js +5 -3
  140. package/src/components/header/QHeader.js +5 -3
  141. package/src/components/input/use-mask.js +1 -1
  142. package/src/components/item/QItem.js +1 -0
  143. package/src/components/item/QList.js +1 -1
  144. package/src/components/option-group/QOptionGroup.js +1 -1
  145. package/src/components/page/QPage.js +11 -4
  146. package/src/components/page/QPageContainer.js +5 -3
  147. package/src/components/page-sticky/use-page-sticky.js +5 -3
  148. package/src/components/pagination/QPagination.js +265 -188
  149. package/src/components/pagination/QPagination.json +82 -65
  150. package/src/components/pagination/QPagination.sass +14 -0
  151. package/src/components/pull-to-refresh/QPullToRefresh.js +1 -4
  152. package/src/components/resize-observer/QResizeObserver.js +14 -10
  153. package/src/components/stepper/QStep.js +7 -5
  154. package/src/components/tab-panels/QTabPanel.js +1 -1
  155. package/src/components/tabs/QTabs.js +2 -9
  156. package/src/components/tabs/QTabs.json +1 -1
  157. package/src/components/tabs/use-tab.js +5 -3
  158. package/src/components/timeline/QTimelineEntry.js +5 -3
  159. package/src/components/toolbar/QToolbar.js +1 -1
  160. package/src/components/tooltip/QTooltip.js +1 -1
  161. package/src/components/tree/QTree.js +33 -20
  162. package/src/components/tree/QTree.json +7 -0
  163. package/src/components/uploader/QUploaderAddTrigger.js +7 -3
  164. package/src/composables/private/use-file.js +10 -1
  165. package/src/directives/TouchHold.js +10 -3
  166. package/src/directives/TouchPan.js +21 -8
  167. package/src/directives/TouchPan.json +0 -5
  168. package/src/directives/TouchRepeat.js +20 -6
  169. package/src/directives/TouchSwipe.js +10 -3
  170. package/src/utils/morph.js +7 -3
  171. package/src/utils/private/symbols.js +2 -0
@@ -12,7 +12,7 @@
12
12
  },
13
13
 
14
14
  "min": {
15
- "type": "Number",
15
+ "type": [ "Number", "String" ],
16
16
  "desc": "Minimum page (must be lower than 'max')",
17
17
  "default": 1,
18
18
  "examples": [ 3 ],
@@ -20,58 +20,18 @@
20
20
  },
21
21
 
22
22
  "max": {
23
- "type": "Number",
23
+ "type": [ "Number", "String" ],
24
24
  "desc": "Number of last page (must be higher than 'min')",
25
25
  "required": true,
26
26
  "examples": [ 10 ],
27
27
  "category": "model"
28
28
  },
29
29
 
30
- "color": {
31
- "extends": "color",
32
- "default": "primary"
33
- },
34
-
35
- "text-color": {
36
- "extends": "text-color"
37
- },
38
-
39
- "active-color": {
40
- "extends": "color",
41
- "default": "primary"
42
- },
43
-
44
- "active-text-color": {
45
- "extends": "text-color"
46
- },
47
-
48
30
  "dark": {
49
31
  "extends": "dark",
50
32
  "desc": "Notify the component that the background is a dark color (useful when you are using it along with the 'input' prop)"
51
33
  },
52
34
 
53
- "input-style": {
54
- "type": [ "String", "Array", "Object" ],
55
- "tsType": "VueStyleProp",
56
- "desc": "Style definitions to be attributed to the input (if using one)",
57
- "examples": [
58
- "background-color: #ff0000",
59
- ":input-style=\"{ backgroundColor: '#ff0000' }\""
60
- ],
61
- "category": "style"
62
- },
63
-
64
- "input-class": {
65
- "type": [ "String", "Array", "Object" ],
66
- "tsType": "VueClassProp",
67
- "desc": "Class definitions to be attributed to the input (if using one)",
68
- "examples": [
69
- "my-special-class",
70
- ":input-class=\"{ 'my-special-class': <condition> }\""
71
- ],
72
- "category": "style"
73
- },
74
-
75
35
  "size": {
76
36
  "type": "String",
77
37
  "desc": "Button size in CSS units, including unit name",
@@ -149,54 +109,76 @@
149
109
  },
150
110
 
151
111
  "max-pages": {
152
- "type": "Number",
112
+ "type": [ "Number", "String" ],
153
113
  "default": 0,
154
114
  "desc": "Maximum number of page links to display at a time; 0 means Infinite",
155
115
  "examples": [ 5 ],
156
- "category": "model"
116
+ "category": "content"
157
117
  },
158
118
 
159
- "ripple": {
160
- "type": [ "Boolean", "Object" ],
161
- "desc": "Configure buttons material ripple (disable it by setting it to 'false' or supply a config object); Does not applies to boundary and ellipsis buttons",
162
- "default": true,
163
- "examples": [ false, "{ early: true, center: true, color: 'teal', keyCodes: [] }" ],
119
+ "flat": {
120
+ "type": "Boolean",
121
+ "desc": "Use 'flat' design for non-active buttons (it's the default option)",
164
122
  "category": "style"
165
123
  },
166
124
 
167
- "round": {
125
+ "outline": {
168
126
  "type": "Boolean",
169
- "desc": "Makes a circle shaped button for all buttons",
127
+ "desc": "Use 'outline' design for non-active buttons",
170
128
  "category": "style"
171
129
  },
172
130
 
173
- "rounded": {
131
+ "unelevated": {
174
132
  "type": "Boolean",
175
- "desc": "Applies a more prominent border-radius for a squared shape button for all buttons",
133
+ "desc": "Remove shadow for non-active buttons",
176
134
  "category": "style"
177
135
  },
178
136
 
179
- "flat": {
137
+ "push": {
180
138
  "type": "Boolean",
181
- "desc": "Use 'flat' design for current page button",
139
+ "desc": "Use 'push' design for non-active buttons",
182
140
  "category": "style"
183
141
  },
184
142
 
185
- "outline": {
186
- "type": "Boolean",
187
- "desc": "Use 'outline' design for current page button",
188
- "category": "style"
143
+ "color": {
144
+ "extends": "color",
145
+ "desc": "Color name from the Quasar Color Palette for the non-active buttons",
146
+ "default": "primary"
189
147
  },
190
148
 
191
- "unelevated": {
149
+ "text-color": {
150
+ "extends": "text-color",
151
+ "desc": "Text color name from the Quasar Color Palette for the ACTIVE buttons"
152
+ },
153
+
154
+ "active-design": {
155
+ "type": "String",
156
+ "desc": "The design of the ACTIVE button, similar to the flat/outline/push/unelevated props (but those are used for non-active buttons)",
157
+ "values": [ "flat", "outline", "push", "unelevated" ],
158
+ "category": "style",
159
+ "addedIn": "v2.10"
160
+ },
161
+
162
+ "active-color": {
163
+ "extends": "color",
164
+ "desc": "Color name from the Quasar Color Palette for the ACTIVE button",
165
+ "default": "primary"
166
+ },
167
+
168
+ "active-text-color": {
169
+ "extends": "text-color",
170
+ "desc": "Text color name from the Quasar Color Palette for the ACTIVE button"
171
+ },
172
+
173
+ "round": {
192
174
  "type": "Boolean",
193
- "desc": "Remove shadow for current page button",
175
+ "desc": "Makes a circle shaped button for all buttons",
194
176
  "category": "style"
195
177
  },
196
178
 
197
- "push": {
179
+ "rounded": {
198
180
  "type": "Boolean",
199
- "desc": "Use 'push' design for current page button",
181
+ "desc": "Applies a more prominent border-radius for a squared shape button for all buttons",
200
182
  "category": "style"
201
183
  },
202
184
 
@@ -206,8 +188,13 @@
206
188
  "category": "style"
207
189
  },
208
190
 
209
- "dense": {
210
- "extends": "dense"
191
+ "gutter": {
192
+ "type": "String",
193
+ "desc": "Apply custom gutter; Size in CSS units, including unit name or standard size name (none|xs|sm|md|lg|xl)",
194
+ "default": "2px",
195
+ "examples": [ "16px", "10px 5px", "2rem", "xs", "md lg", "2px 2px 5px 7px" ],
196
+ "category": "style",
197
+ "addedIn": "v2.10"
211
198
  },
212
199
 
213
200
  "padding": {
@@ -215,6 +202,36 @@
215
202
  "desc": "Apply custom padding (vertical [horizontal]); Size in CSS units, including unit name or standard size name (none|xs|sm|md|lg|xl); Also removes the min width and height when set",
216
203
  "examples": [ "16px", "10px 5px", "2rem", "xs", "md lg", "2px 2px 5px 7px" ],
217
204
  "category": "style"
205
+ },
206
+
207
+ "input-style": {
208
+ "type": [ "String", "Array", "Object" ],
209
+ "tsType": "VueStyleProp",
210
+ "desc": "Style definitions to be attributed to the input (if using one)",
211
+ "examples": [
212
+ "background-color: #ff0000",
213
+ ":input-style=\"{ backgroundColor: '#ff0000' }\""
214
+ ],
215
+ "category": "style"
216
+ },
217
+
218
+ "input-class": {
219
+ "type": [ "String", "Array", "Object" ],
220
+ "tsType": "VueClassProp",
221
+ "desc": "Class definitions to be attributed to the input (if using one)",
222
+ "examples": [
223
+ "my-special-class",
224
+ ":input-class=\"{ 'my-special-class': <condition> }\""
225
+ ],
226
+ "category": "style"
227
+ },
228
+
229
+ "ripple": {
230
+ "type": [ "Boolean", "Object" ],
231
+ "desc": "Configure buttons material ripple (disable it by setting it to 'false' or supply a config object); Does not applies to boundary and ellipsis buttons",
232
+ "default": true,
233
+ "examples": [ false, "{ early: true, center: true, color: 'teal', keyCodes: [] }" ],
234
+ "category": "style"
218
235
  }
219
236
  },
220
237
 
@@ -1,3 +1,4 @@
1
+
1
2
  .q-pagination
2
3
  input
3
4
  text-align: center
@@ -7,3 +8,16 @@
7
8
  input::-webkit-inner-spin-button
8
9
  -webkit-appearance: none
9
10
  margin: 0
11
+
12
+ &__content
13
+ --q-pagination-gutter-parent: -2px
14
+ --q-pagination-gutter-child: 2px
15
+
16
+ margin-top: var(--q-pagination-gutter-parent)
17
+ margin-left: var(--q-pagination-gutter-parent)
18
+
19
+ &__content > .q-btn,
20
+ &__content > .q-input,
21
+ &__middle > .q-btn
22
+ margin-top: var(--q-pagination-gutter-child)
23
+ margin-left: var(--q-pagination-gutter-child)
@@ -111,10 +111,7 @@ export default createComponent({
111
111
 
112
112
  const directives = computed(() => {
113
113
  // if props.disable === false
114
- const modifiers = {
115
- down: true,
116
- mightPrevent: true
117
- }
114
+ const modifiers = { down: true }
118
115
 
119
116
  if (props.noMouse !== true) {
120
117
  modifiers.mouse = true
@@ -58,17 +58,21 @@ export default createComponent({
58
58
  if (hasObserver === true) {
59
59
  let observer
60
60
 
61
- onMounted(() => {
62
- nextTick(() => {
63
- targetEl = proxy.$el.parentNode
61
+ // initialize as soon as possible
62
+ const init = stop => {
63
+ targetEl = proxy.$el.parentNode
64
64
 
65
- if (targetEl) {
66
- observer = new ResizeObserver(trigger)
67
- observer.observe(targetEl)
68
- emitEvent()
69
- }
70
- })
71
- })
65
+ if (targetEl) {
66
+ observer = new ResizeObserver(trigger)
67
+ observer.observe(targetEl)
68
+ emitEvent()
69
+ }
70
+ else if (stop !== true) {
71
+ nextTick(() => { init(true) })
72
+ }
73
+ }
74
+
75
+ onMounted(() => { init() })
72
76
 
73
77
  onBeforeUnmount(() => {
74
78
  clearTimeout(timer)
@@ -7,7 +7,7 @@ import { usePanelChildProps } from '../../composables/private/use-panel.js'
7
7
  import useCache from '../../composables/private/use-cache.js'
8
8
 
9
9
  import { createComponent } from '../../utils/private/create.js'
10
- import { stepperKey } from '../../utils/private/symbols.js'
10
+ import { stepperKey, emptyRenderFn } from '../../utils/private/symbols.js'
11
11
  import { hSlot } from '../../utils/private/render.js'
12
12
 
13
13
  function getStepWrapper (slots) {
@@ -61,9 +61,11 @@ export default createComponent({
61
61
  setup (props, { slots, emit }) {
62
62
  const { proxy: { $q } } = getCurrentInstance()
63
63
 
64
- const $stepper = inject(stepperKey, () => {
65
- console.error('QStep needs to be child of QStepper')
66
- })
64
+ const $stepper = inject(stepperKey, emptyRenderFn)
65
+ if ($stepper === emptyRenderFn) {
66
+ console.error('QStep needs to be a child of QStepper')
67
+ return emptyRenderFn
68
+ }
67
69
 
68
70
  const { getCacheWithFn } = useCache()
69
71
 
@@ -121,7 +123,7 @@ export default createComponent({
121
123
 
122
124
  return () => h(
123
125
  'div',
124
- { ref: rootRef, class: 'q-stepper__step', ...scrollEvent.value },
126
+ { ref: rootRef, class: 'q-stepper__step', role: 'tabpanel', ...scrollEvent.value },
125
127
  $stepper.value.vertical === true
126
128
  ? [
127
129
  h(StepHeader, {
@@ -11,6 +11,6 @@ export default createComponent({
11
11
  props: usePanelChildProps,
12
12
 
13
13
  setup (_, { slots }) {
14
- return () => h('div', { class: 'q-tab-panel' }, hSlot(slots.default))
14
+ return () => h('div', { class: 'q-tab-panel', role: 'tabpanel' }, hSlot(slots.default))
15
15
  }
16
16
  })
@@ -572,8 +572,8 @@ export default createComponent({
572
572
 
573
573
  recalculateScroll()
574
574
 
575
- // if it's a QTab
576
- if (tabData.routeData === void 0) {
575
+ // if it's a QTab or we don't have Vue Router
576
+ if (tabData.routeData === void 0 || proxy.$route === void 0) {
577
577
  // we should position to the currently active tab (if any)
578
578
  registerScrollToTabTimeout(() => {
579
579
  if (scrollable.value === true) {
@@ -597,13 +597,6 @@ export default createComponent({
597
597
  }
598
598
  }
599
599
 
600
- /*
601
- * Vue has an aggressive diff (in-place replacement) so we cannot
602
- * ensure that the instance getting destroyed is the actual tab
603
- * reported here. As a result, we cannot use its name or check
604
- * if it's a route one to make the necessary updates. We need to
605
- * always check the existing list again and infer the changes.
606
- */
607
600
  function unregisterTab (tabData) {
608
601
  tabDataList.splice(tabDataList.indexOf(tabData), 1)
609
602
  tabDataListLen.value--
@@ -77,7 +77,7 @@
77
77
  "desc": "The class to be set on the active tab",
78
78
  "examples": [ "my-active-class" ],
79
79
  "category": "style",
80
- "addedIn": "2.1.4"
80
+ "addedIn": "v2.1.4"
81
81
  },
82
82
 
83
83
  "left-icon": {
@@ -6,7 +6,7 @@ import Ripple from '../../directives/Ripple.js'
6
6
 
7
7
  import { hMergeSlot } from '../../utils/private/render.js'
8
8
  import { isKeyCode, shouldIgnoreKey } from '../../utils/private/key-composition.js'
9
- import { tabsKey } from '../../utils/private/symbols.js'
9
+ import { tabsKey, emptyRenderFn } from '../../utils/private/symbols.js'
10
10
  import { stopAndPrevent } from '../../utils/event.js'
11
11
  import uid from '../../utils/uid.js'
12
12
  import { isDeepEqual } from '../../utils/is.js'
@@ -41,9 +41,11 @@ export const useTabProps = {
41
41
  }
42
42
 
43
43
  export default function (props, slots, emit, routeData) {
44
- const $tabs = inject(tabsKey, () => {
44
+ const $tabs = inject(tabsKey, emptyRenderFn)
45
+ if ($tabs === emptyRenderFn) {
45
46
  console.error('QTab/QRouteTab component needs to be child of QTabs')
46
- })
47
+ return emptyRenderFn
48
+ }
47
49
 
48
50
  const { proxy } = getCurrentInstance()
49
51
 
@@ -4,7 +4,7 @@ import QIcon from '../icon/QIcon.js'
4
4
 
5
5
  import { createComponent } from '../../utils/private/create.js'
6
6
  import { hSlot, hUniqueSlot } from '../../utils/private/render.js'
7
- import { timelineKey } from '../../utils/private/symbols.js'
7
+ import { timelineKey, emptyRenderFn } from '../../utils/private/symbols.js'
8
8
 
9
9
  export default createComponent({
10
10
  name: 'QTimelineEntry',
@@ -32,9 +32,11 @@ export default createComponent({
32
32
  },
33
33
 
34
34
  setup (props, { slots }) {
35
- const $timeline = inject(timelineKey, () => {
35
+ const $timeline = inject(timelineKey, emptyRenderFn)
36
+ if ($timeline === emptyRenderFn) {
36
37
  console.error('QTimelineEntry needs to be child of QTimeline')
37
- })
38
+ return emptyRenderFn
39
+ }
38
40
 
39
41
  const classes = computed(() =>
40
42
  `q-timeline__entry q-timeline__entry--${ props.side }`
@@ -16,6 +16,6 @@ export default createComponent({
16
16
  + (props.inset === true ? ' q-toolbar--inset' : '')
17
17
  )
18
18
 
19
- return () => h('div', { class: classes.value }, hSlot(slots.default))
19
+ return () => h('div', { class: classes.value, role: 'toolbar' }, hSlot(slots.default))
20
20
  }
21
21
  })
@@ -285,7 +285,7 @@ export default createComponent({
285
285
  attrs.style,
286
286
  transitionStyle.value
287
287
  ],
288
- role: 'complementary'
288
+ role: 'tooltip'
289
289
  }, hSlot(slots.default))
290
290
  : null
291
291
  }
@@ -68,6 +68,7 @@ export default createComponent({
68
68
 
69
69
  duration: Number,
70
70
  noConnectors: Boolean,
71
+ noTransition: Boolean,
71
72
 
72
73
  noNodesLabel: String,
73
74
  noResultsLabel: String
@@ -140,7 +141,6 @@ export default createComponent({
140
141
  const
141
142
  key = node[ props.nodeKey ],
142
143
  isParent = node[ props.childrenKey ] && node[ props.childrenKey ].length > 0,
143
- isLeaf = isParent !== true,
144
144
  selectable = node.disabled !== true && hasSelection.value === true && node.selectable !== false,
145
145
  expandable = node.disabled !== true && node.expandable !== false,
146
146
  hasTicking = tickStrategy !== 'none',
@@ -166,7 +166,6 @@ export default createComponent({
166
166
  key,
167
167
  parent,
168
168
  isParent,
169
- isLeaf,
170
169
  lazy: localLazy,
171
170
  disabled: node.disabled,
172
171
  link: node.disabled !== true && (selectable === true || (expandable === true && (isParent === true || localLazy === true))),
@@ -186,7 +185,7 @@ export default createComponent({
186
185
  leafTicking,
187
186
  ticked: strictTicking === true
188
187
  ? innerTicked.value.includes(key)
189
- : (isLeaf === true ? innerTicked.value.includes(key) : false)
188
+ : (isParent === true ? false : innerTicked.value.includes(key))
190
189
  }
191
190
 
192
191
  meta[ key ] = m
@@ -586,23 +585,37 @@ export default createComponent({
586
585
  ]),
587
586
 
588
587
  isParent === true
589
- ? h(QSlideTransition, {
590
- duration: props.duration,
591
- onShow,
592
- onHide
593
- }, () => withDirectives(
594
- h('div', {
595
- class: 'q-tree__node-collapsible' + textColorClass.value,
596
- key: `${ key }__q`
597
- }, [
598
- body,
599
- h('div', {
600
- class: 'q-tree__children'
601
- + (m.disabled === true ? ' q-tree__node--disabled' : '')
602
- }, children)
603
- ]),
604
- [ [ vShow, m.expanded ] ]
605
- ))
588
+ ? (
589
+ props.noTransition === true
590
+ ? h('div', {
591
+ class: 'q-tree__node-collapsible' + textColorClass.value,
592
+ key: `${ key }__q`
593
+ }, [
594
+ body,
595
+ h('div', {
596
+ class: 'q-tree__children'
597
+ + (m.disabled === true ? ' q-tree__node--disabled' : '')
598
+ }, m.expanded ? children : null)
599
+ ])
600
+
601
+ : h(QSlideTransition, {
602
+ duration: props.duration,
603
+ onShow,
604
+ onHide
605
+ }, () => withDirectives(
606
+ h('div', {
607
+ class: 'q-tree__node-collapsible' + textColorClass.value,
608
+ key: `${ key }__q`
609
+ }, [
610
+ body,
611
+ h('div', {
612
+ class: 'q-tree__children'
613
+ + (m.disabled === true ? ' q-tree__node--disabled' : '')
614
+ }, children)
615
+ ]),
616
+ [ [ vShow, m.expanded ] ]
617
+ ))
618
+ )
606
619
  : body
607
620
  ])
608
621
  }
@@ -126,6 +126,13 @@
126
126
  "category": "behavior"
127
127
  },
128
128
 
129
+ "no-transition": {
130
+ "type": "Boolean",
131
+ "desc": "Turn off transition effects when expanding/collapsing nodes; Also enhances perf by a lot as a side-effect; Recommended for big trees",
132
+ "category": "behavior",
133
+ "addedIn": "v2.9.2"
134
+ },
135
+
129
136
  "filter": {
130
137
  "type": "String",
131
138
  "desc": "The text value to be used for filtering nodes",
@@ -1,14 +1,18 @@
1
1
  import { inject } from 'vue'
2
2
 
3
3
  import { createComponent } from '../../utils/private/create.js'
4
- import { uploaderKey } from '../../utils/private/symbols.js'
4
+ import { uploaderKey, emptyRenderFn } from '../../utils/private/symbols.js'
5
5
 
6
6
  export default createComponent({
7
7
  name: 'QUploaderAddTrigger',
8
8
 
9
9
  setup () {
10
- return inject(uploaderKey, () => {
10
+ const $trigger = inject(uploaderKey, emptyRenderFn)
11
+
12
+ if ($trigger === emptyRenderFn) {
11
13
  console.error('QUploaderAddTrigger needs to be child of QUploader')
12
- })
14
+ }
15
+
16
+ return $trigger
13
17
  }
14
18
  })
@@ -1,5 +1,6 @@
1
1
  import { h, ref, computed, getCurrentInstance } from 'vue'
2
2
 
3
+ import { client } from '../../plugins/Platform.js'
3
4
  import { stop, stopAndPrevent } from '../../utils/event.js'
4
5
 
5
6
  function filterFiles (files, rejectedFiles, failedPropValidation, filterFn) {
@@ -187,7 +188,14 @@ export default function ({
187
188
 
188
189
  function onDragleave (e) {
189
190
  stopAndPrevent(e)
190
- e.relatedTarget !== dndRef.value && (dnd.value = false)
191
+
192
+ // Safari bug: relatedTarget is null for over 10 years
193
+ // https://bugs.webkit.org/show_bug.cgi?id=66547
194
+ const gone = e.relatedTarget !== null || client.is.safari !== true
195
+ ? e.relatedTarget !== dndRef.value
196
+ : document.elementsFromPoint(e.clientX, e.clientY).includes(dndRef.value) === false
197
+
198
+ gone === true && (dnd.value = false)
191
199
  }
192
200
 
193
201
  function onDrop (e) {
@@ -221,6 +229,7 @@ export default function ({
221
229
  pickFiles,
222
230
  addFiles,
223
231
  onDragover,
232
+ onDragleave,
224
233
  processFiles,
225
234
  getDndNode,
226
235
 
@@ -126,9 +126,16 @@ export default createDirective(__QUASAR_SSR_SERVER__
126
126
 
127
127
  el.__qtouchhold = ctx
128
128
 
129
- modifiers.mouse === true && addEvt(ctx, 'main', [
130
- [ el, 'mousedown', 'mouseStart', `passive${ modifiers.mouseCapture === true ? 'Capture' : '' }` ]
131
- ])
129
+ if (modifiers.mouse === true) {
130
+ // account for UMD too where modifiers will be lowercased to work
131
+ const capture = modifiers.mouseCapture === true || modifiers.mousecapture === true
132
+ ? 'Capture'
133
+ : ''
134
+
135
+ addEvt(ctx, 'main', [
136
+ [ el, 'mousedown', 'mouseStart', `passive${ capture }` ]
137
+ ])
138
+ }
132
139
 
133
140
  client.has.touch === true && addEvt(ctx, 'main', [
134
141
  [ el, 'touchstart', 'touchStart', `passive${ modifiers.capture === true ? 'Capture' : '' }` ],