quasar 2.9.2 → 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 (159) 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/icon-set/bootstrap-icons.umd.prod.js +1 -1
  6. package/dist/icon-set/eva-icons.umd.prod.js +1 -1
  7. package/dist/icon-set/fontawesome-v5-pro.umd.prod.js +1 -1
  8. package/dist/icon-set/fontawesome-v5.umd.prod.js +1 -1
  9. package/dist/icon-set/fontawesome-v6-pro.umd.prod.js +1 -1
  10. package/dist/icon-set/fontawesome-v6.umd.prod.js +1 -1
  11. package/dist/icon-set/ionicons-v4.umd.prod.js +1 -1
  12. package/dist/icon-set/line-awesome.umd.prod.js +1 -1
  13. package/dist/icon-set/material-icons-outlined.umd.prod.js +1 -1
  14. package/dist/icon-set/material-icons-round.umd.prod.js +1 -1
  15. package/dist/icon-set/material-icons-sharp.umd.prod.js +1 -1
  16. package/dist/icon-set/material-icons.umd.prod.js +1 -1
  17. package/dist/icon-set/material-symbols-outlined.umd.prod.js +1 -1
  18. package/dist/icon-set/material-symbols-rounded.umd.prod.js +1 -1
  19. package/dist/icon-set/material-symbols-sharp.umd.prod.js +1 -1
  20. package/dist/icon-set/mdi-v3.umd.prod.js +1 -1
  21. package/dist/icon-set/mdi-v4.umd.prod.js +1 -1
  22. package/dist/icon-set/mdi-v5.umd.prod.js +1 -1
  23. package/dist/icon-set/mdi-v6.umd.prod.js +1 -1
  24. package/dist/icon-set/svg-bootstrap-icons.umd.prod.js +1 -1
  25. package/dist/icon-set/svg-eva-icons.umd.prod.js +1 -1
  26. package/dist/icon-set/svg-fontawesome-v5.umd.prod.js +1 -1
  27. package/dist/icon-set/svg-fontawesome-v6.umd.prod.js +1 -1
  28. package/dist/icon-set/svg-ionicons-v4.umd.prod.js +1 -1
  29. package/dist/icon-set/svg-ionicons-v5.umd.prod.js +1 -1
  30. package/dist/icon-set/svg-ionicons-v6.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-material-symbols-outlined.umd.prod.js +1 -1
  37. package/dist/icon-set/svg-material-symbols-rounded.umd.prod.js +1 -1
  38. package/dist/icon-set/svg-material-symbols-sharp.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-TN.umd.prod.js +1 -1
  43. package/dist/lang/ar.umd.prod.js +1 -1
  44. package/dist/lang/az-Latn.umd.prod.js +1 -1
  45. package/dist/lang/bg.umd.prod.js +1 -1
  46. package/dist/lang/bn.umd.prod.js +1 -1
  47. package/dist/lang/ca.umd.prod.js +1 -1
  48. package/dist/lang/cs.umd.prod.js +1 -1
  49. package/dist/lang/da.umd.prod.js +1 -1
  50. package/dist/lang/de.umd.prod.js +1 -1
  51. package/dist/lang/el.umd.prod.js +1 -1
  52. package/dist/lang/en-GB.umd.prod.js +1 -1
  53. package/dist/lang/en-US.umd.prod.js +1 -1
  54. package/dist/lang/eo.umd.prod.js +1 -1
  55. package/dist/lang/es.umd.prod.js +1 -1
  56. package/dist/lang/et.umd.prod.js +1 -1
  57. package/dist/lang/eu.umd.prod.js +1 -1
  58. package/dist/lang/fa-IR.umd.prod.js +1 -1
  59. package/dist/lang/fa.umd.prod.js +1 -1
  60. package/dist/lang/fi.umd.prod.js +1 -1
  61. package/dist/lang/fr.umd.prod.js +1 -1
  62. package/dist/lang/gn.umd.prod.js +1 -1
  63. package/dist/lang/he.umd.prod.js +1 -1
  64. package/dist/lang/hr.umd.prod.js +1 -1
  65. package/dist/lang/hu.umd.prod.js +1 -1
  66. package/dist/lang/id.umd.prod.js +1 -1
  67. package/dist/lang/is.umd.prod.js +1 -1
  68. package/dist/lang/it.umd.prod.js +1 -1
  69. package/dist/lang/ja.umd.prod.js +1 -1
  70. package/dist/lang/km.umd.prod.js +1 -1
  71. package/dist/lang/ko-KR.umd.prod.js +1 -1
  72. package/dist/lang/kur-CKB.umd.prod.js +1 -1
  73. package/dist/lang/kz.umd.prod.js +1 -1
  74. package/dist/lang/lt.umd.prod.js +1 -1
  75. package/dist/lang/lu.umd.prod.js +1 -1
  76. package/dist/lang/lv.umd.prod.js +1 -1
  77. package/dist/lang/ml.umd.prod.js +1 -1
  78. package/dist/lang/mm.umd.prod.js +1 -1
  79. package/dist/lang/ms.umd.prod.js +1 -1
  80. package/dist/lang/my.umd.prod.js +1 -1
  81. package/dist/lang/nb-NO.umd.prod.js +1 -1
  82. package/dist/lang/nl.umd.prod.js +1 -1
  83. package/dist/lang/pl.umd.prod.js +1 -1
  84. package/dist/lang/pt-BR.umd.prod.js +1 -1
  85. package/dist/lang/pt.umd.prod.js +1 -1
  86. package/dist/lang/ro.umd.prod.js +1 -1
  87. package/dist/lang/ru.umd.prod.js +1 -1
  88. package/dist/lang/sk.umd.prod.js +1 -1
  89. package/dist/lang/sl.umd.prod.js +1 -1
  90. package/dist/lang/sm.umd.prod.js +1 -1
  91. package/dist/lang/sr-CYR.umd.prod.js +1 -1
  92. package/dist/lang/sr.umd.prod.js +1 -1
  93. package/dist/lang/sv.umd.prod.js +1 -1
  94. package/dist/lang/ta.umd.prod.js +1 -1
  95. package/dist/lang/th.umd.prod.js +1 -1
  96. package/dist/lang/tr.umd.prod.js +1 -1
  97. package/dist/lang/ug.umd.prod.js +1 -1
  98. package/dist/lang/uk.umd.prod.js +1 -1
  99. package/dist/lang/uz-Cyrl.umd.prod.js +1 -1
  100. package/dist/lang/uz-Latn.umd.prod.js +1 -1
  101. package/dist/lang/vi.umd.prod.js +1 -1
  102. package/dist/lang/zh-CN.umd.prod.js +1 -1
  103. package/dist/lang/zh-TW.umd.prod.js +1 -1
  104. package/dist/quasar.cjs.prod.js +2 -2
  105. package/dist/quasar.css +10 -0
  106. package/dist/quasar.esm.js +450 -300
  107. package/dist/quasar.esm.prod.js +2 -2
  108. package/dist/quasar.prod.css +1 -1
  109. package/dist/quasar.rtl.css +26 -0
  110. package/dist/quasar.rtl.prod.css +1 -1
  111. package/dist/quasar.sass +11 -1
  112. package/dist/quasar.umd.js +450 -300
  113. package/dist/quasar.umd.prod.js +2 -2
  114. package/dist/transforms/auto-import.json +7 -3
  115. package/dist/transforms/import-map.json +2 -0
  116. package/dist/types/index.d.ts +66 -51
  117. package/dist/vetur/quasar-attributes.json +61 -49
  118. package/dist/vetur/quasar-tags.json +16 -13
  119. package/dist/web-types/web-types.json +121 -92
  120. package/package.json +1 -1
  121. package/src/components/badge/QBadge.js +1 -1
  122. package/src/components/breadcrumbs/QBreadcrumbsEl.json +0 -4
  123. package/src/components/breadcrumbs/__tests__/BasicBreadcrumbs.vue +7 -0
  124. package/src/components/breadcrumbs/__tests__/BreadcrumbWithSeparatorSlot.vue +11 -0
  125. package/src/components/breadcrumbs/__tests__/QBreadcrumbs.spec.js +112 -0
  126. package/src/components/breadcrumbs/__tests__/QBreadcrumbsEl.spec.js +87 -0
  127. package/src/components/btn/use-btn.js +24 -14
  128. package/src/components/btn-dropdown/QBtnDropdown.js +39 -16
  129. package/src/components/btn-dropdown/QBtnDropdown.json +1 -1
  130. package/src/components/btn-toggle/QBtnToggle.js +14 -14
  131. package/src/components/checkbox/use-checkbox.js +1 -1
  132. package/src/components/chip/QChip.js +14 -11
  133. package/src/components/dialog/QDialog.js +2 -1
  134. package/src/components/dialog-bottom-sheet/BottomSheet.js +6 -2
  135. package/src/components/drawer/QDrawer.js +5 -3
  136. package/src/components/footer/QFooter.js +5 -3
  137. package/src/components/header/QHeader.js +5 -3
  138. package/src/components/input/use-mask.js +1 -1
  139. package/src/components/item/QItem.js +1 -0
  140. package/src/components/item/QList.js +1 -1
  141. package/src/components/option-group/QOptionGroup.js +1 -1
  142. package/src/components/page/QPage.js +11 -4
  143. package/src/components/page/QPageContainer.js +5 -3
  144. package/src/components/page-sticky/use-page-sticky.js +5 -3
  145. package/src/components/pagination/QPagination.js +265 -188
  146. package/src/components/pagination/QPagination.json +82 -65
  147. package/src/components/pagination/QPagination.sass +14 -0
  148. package/src/components/resize-observer/QResizeObserver.js +14 -10
  149. package/src/components/stepper/QStep.js +7 -5
  150. package/src/components/tab-panels/QTabPanel.js +1 -1
  151. package/src/components/tabs/QTabs.js +0 -7
  152. package/src/components/tabs/QTabs.json +1 -1
  153. package/src/components/tabs/use-tab.js +5 -3
  154. package/src/components/timeline/QTimelineEntry.js +5 -3
  155. package/src/components/toolbar/QToolbar.js +1 -1
  156. package/src/components/tooltip/QTooltip.js +1 -1
  157. package/src/components/uploader/QUploaderAddTrigger.js +7 -3
  158. package/src/composables/private/use-file.js +10 -1
  159. 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)
@@ -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
  })
@@ -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
  }
@@ -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
 
@@ -7,3 +7,5 @@ export const fabKey = '_q_f_'
7
7
  export const formKey = '_q_fo_'
8
8
  export const tabsKey = '_q_tabs_'
9
9
  export const uploaderKey = '_q_u_'
10
+
11
+ export const emptyRenderFn = () => {}