quasar 2.8.4 → 2.9.1

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 (169) hide show
  1. package/dist/api/QBreadcrumbsEl.json +52 -0
  2. package/dist/api/QBtn.json +41 -6
  3. package/dist/api/QBtnDropdown.json +1 -1
  4. package/dist/api/QChip.json +1 -1
  5. package/dist/api/QEditor.json +7 -0
  6. package/dist/api/QExpansionItem.json +1 -1
  7. package/dist/api/QItem.json +52 -0
  8. package/dist/api/QRating.json +13 -0
  9. package/dist/api/QRouteTab.json +42 -6
  10. package/dist/icon-set/bootstrap-icons.umd.prod.js +1 -1
  11. package/dist/icon-set/eva-icons.umd.prod.js +1 -1
  12. package/dist/icon-set/fontawesome-v5-pro.umd.prod.js +1 -1
  13. package/dist/icon-set/fontawesome-v5.umd.prod.js +1 -1
  14. package/dist/icon-set/fontawesome-v6-pro.umd.prod.js +1 -1
  15. package/dist/icon-set/fontawesome-v6.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/material-symbols-outlined.umd.prod.js +1 -1
  23. package/dist/icon-set/material-symbols-rounded.umd.prod.js +1 -1
  24. package/dist/icon-set/material-symbols-sharp.umd.prod.js +1 -1
  25. package/dist/icon-set/mdi-v3.umd.prod.js +1 -1
  26. package/dist/icon-set/mdi-v4.umd.prod.js +1 -1
  27. package/dist/icon-set/mdi-v5.umd.prod.js +1 -1
  28. package/dist/icon-set/mdi-v6.umd.prod.js +1 -1
  29. package/dist/icon-set/svg-bootstrap-icons.umd.prod.js +1 -1
  30. package/dist/icon-set/svg-eva-icons.umd.prod.js +1 -1
  31. package/dist/icon-set/svg-fontawesome-v5.umd.prod.js +1 -1
  32. package/dist/icon-set/svg-fontawesome-v6.umd.prod.js +1 -1
  33. package/dist/icon-set/svg-ionicons-v4.umd.prod.js +1 -1
  34. package/dist/icon-set/svg-ionicons-v5.umd.prod.js +1 -1
  35. package/dist/icon-set/svg-ionicons-v6.umd.prod.js +1 -1
  36. package/dist/icon-set/svg-line-awesome.umd.prod.js +1 -1
  37. package/dist/icon-set/svg-material-icons-outlined.umd.prod.js +1 -1
  38. package/dist/icon-set/svg-material-icons-round.umd.prod.js +1 -1
  39. package/dist/icon-set/svg-material-icons-sharp.umd.prod.js +1 -1
  40. package/dist/icon-set/svg-material-icons.umd.prod.js +1 -1
  41. package/dist/icon-set/svg-material-symbols-outlined.umd.prod.js +1 -1
  42. package/dist/icon-set/svg-material-symbols-rounded.umd.prod.js +1 -1
  43. package/dist/icon-set/svg-material-symbols-sharp.umd.prod.js +1 -1
  44. package/dist/icon-set/svg-mdi-v6.umd.prod.js +1 -1
  45. package/dist/icon-set/svg-themify.umd.prod.js +1 -1
  46. package/dist/icon-set/themify.umd.prod.js +1 -1
  47. package/dist/lang/ar-TN.umd.prod.js +1 -1
  48. package/dist/lang/ar.umd.prod.js +1 -1
  49. package/dist/lang/az-Latn.umd.prod.js +1 -1
  50. package/dist/lang/bg.umd.prod.js +1 -1
  51. package/dist/lang/bn.umd.prod.js +1 -1
  52. package/dist/lang/ca.umd.prod.js +1 -1
  53. package/dist/lang/cs.umd.prod.js +1 -1
  54. package/dist/lang/da.umd.prod.js +1 -1
  55. package/dist/lang/de.umd.prod.js +1 -1
  56. package/dist/lang/el.umd.prod.js +1 -1
  57. package/dist/lang/en-GB.umd.prod.js +1 -1
  58. package/dist/lang/en-US.umd.prod.js +1 -1
  59. package/dist/lang/eo.umd.prod.js +1 -1
  60. package/dist/lang/es.umd.prod.js +1 -1
  61. package/dist/lang/et.umd.prod.js +1 -1
  62. package/dist/lang/eu.umd.prod.js +1 -1
  63. package/dist/lang/fa-IR.umd.prod.js +1 -1
  64. package/dist/lang/fa.umd.prod.js +1 -1
  65. package/dist/lang/fi.umd.prod.js +1 -1
  66. package/dist/lang/fr.umd.prod.js +1 -1
  67. package/dist/lang/gn.umd.prod.js +1 -1
  68. package/dist/lang/he.umd.prod.js +1 -1
  69. package/dist/lang/hr.umd.prod.js +1 -1
  70. package/dist/lang/hu.umd.prod.js +1 -1
  71. package/dist/lang/id.umd.prod.js +1 -1
  72. package/dist/lang/is.umd.prod.js +1 -1
  73. package/dist/lang/it.umd.prod.js +1 -1
  74. package/dist/lang/ja.umd.prod.js +1 -1
  75. package/dist/lang/km.umd.prod.js +1 -1
  76. package/dist/lang/ko-KR.umd.prod.js +1 -1
  77. package/dist/lang/kur-CKB.umd.prod.js +1 -1
  78. package/dist/lang/kz.umd.prod.js +1 -1
  79. package/dist/lang/lt.umd.prod.js +1 -1
  80. package/dist/lang/lu.umd.prod.js +1 -1
  81. package/dist/lang/lv.umd.prod.js +1 -1
  82. package/dist/lang/ml.umd.prod.js +1 -1
  83. package/dist/lang/mm.umd.prod.js +1 -1
  84. package/dist/lang/ms.umd.prod.js +1 -1
  85. package/dist/lang/my.umd.prod.js +1 -1
  86. package/dist/lang/nb-NO.umd.prod.js +1 -1
  87. package/dist/lang/nl.umd.prod.js +2 -2
  88. package/dist/lang/pl.umd.prod.js +1 -1
  89. package/dist/lang/pt-BR.umd.prod.js +1 -1
  90. package/dist/lang/pt.umd.prod.js +1 -1
  91. package/dist/lang/ro.umd.prod.js +1 -1
  92. package/dist/lang/ru.umd.prod.js +1 -1
  93. package/dist/lang/sk.umd.prod.js +1 -1
  94. package/dist/lang/sl.umd.prod.js +1 -1
  95. package/dist/lang/sm.umd.prod.js +1 -1
  96. package/dist/lang/sr-CYR.umd.prod.js +1 -1
  97. package/dist/lang/sr.umd.prod.js +1 -1
  98. package/dist/lang/sv.umd.prod.js +1 -1
  99. package/dist/lang/ta.umd.prod.js +1 -1
  100. package/dist/lang/th.umd.prod.js +1 -1
  101. package/dist/lang/tr.umd.prod.js +1 -1
  102. package/dist/lang/ug.umd.prod.js +1 -1
  103. package/dist/lang/uk.umd.prod.js +1 -1
  104. package/dist/lang/uz-Cyrl.umd.prod.js +1 -1
  105. package/dist/lang/uz-Latn.umd.prod.js +1 -1
  106. package/dist/lang/vi.umd.prod.js +1 -1
  107. package/dist/lang/zh-CN.umd.prod.js +1 -1
  108. package/dist/lang/zh-TW.umd.prod.js +1 -1
  109. package/dist/quasar.cjs.prod.js +2 -2
  110. package/dist/quasar.esm.js +533 -337
  111. package/dist/quasar.esm.prod.js +2 -2
  112. package/dist/quasar.sass +1 -1
  113. package/dist/quasar.umd.js +532 -336
  114. package/dist/quasar.umd.prod.js +2 -2
  115. package/dist/transforms/auto-import.json +7 -3
  116. package/dist/transforms/import-map.json +2 -0
  117. package/dist/types/api/qeditor.d.ts +17 -0
  118. package/dist/types/api.d.ts +1 -0
  119. package/dist/types/index.d.ts +93 -8
  120. package/dist/types/utils/run-sequential-promises.d.ts +1 -1
  121. package/dist/vetur/quasar-attributes.json +4 -0
  122. package/dist/vetur/quasar-tags.json +1 -0
  123. package/dist/web-types/web-types.json +60 -9
  124. package/lang/nl.js +2 -2
  125. package/lang/nl.mjs +2 -2
  126. package/package.json +5 -3
  127. package/src/components/banner/__tests__/QBanner.spec.js +107 -0
  128. package/src/components/bar/__tests__/QBar.spec.js +46 -0
  129. package/src/components/breadcrumbs/QBreadcrumbsEl.js +6 -7
  130. package/src/components/breadcrumbs/QBreadcrumbsEl.json +53 -0
  131. package/src/components/btn/QBtn.js +19 -19
  132. package/src/components/btn/QBtn.json +41 -6
  133. package/src/components/btn/use-btn.js +6 -4
  134. package/src/components/btn-dropdown/QBtnDropdown.json +1 -1
  135. package/src/components/checkbox/QCheckbox.js +1 -2
  136. package/src/components/checkbox/use-checkbox.js +2 -1
  137. package/src/components/chip/QChip.json +1 -1
  138. package/src/components/dialog/QDialog.js +6 -4
  139. package/src/components/drawer/QDrawer.js +7 -4
  140. package/src/components/editor/QEditor.json +9 -0
  141. package/src/components/expansion-item/QExpansionItem.json +1 -1
  142. package/src/components/item/QItem.js +4 -5
  143. package/src/components/item/QItem.json +53 -0
  144. package/src/components/menu/QMenu.js +4 -5
  145. package/src/components/menu/__tests__/QMenu.spec.js +7 -0
  146. package/src/components/popup-edit/QPopupEdit.js +2 -5
  147. package/src/components/radio/QRadio.js +3 -3
  148. package/src/components/rating/QRating.js +48 -10
  149. package/src/components/rating/QRating.json +11 -0
  150. package/src/components/stepper/QStep.js +5 -3
  151. package/src/components/table/QTable.js +3 -5
  152. package/src/components/tabs/QRouteTab.js +6 -4
  153. package/src/components/tabs/QRouteTab.json +42 -6
  154. package/src/components/tabs/QTabs.js +188 -108
  155. package/src/components/tabs/use-tab.js +62 -38
  156. package/src/components/tooltip/QTooltip.js +7 -13
  157. package/src/components/tree/QTree.js +1 -1
  158. package/src/composables/private/__tests__/use-model-toggle.spec.js +2 -0
  159. package/src/composables/private/__tests__/use-transition.spec.js +4 -0
  160. package/src/composables/private/use-router-link.js +80 -43
  161. package/src/composables/private/use-tick.js +15 -9
  162. package/src/composables/private/use-timeout.js +20 -7
  163. package/src/directives/TouchPan.js +1 -1
  164. package/src/directives/TouchRepeat.js +1 -1
  165. package/src/directives/TouchSwipe.js +1 -1
  166. package/src/utils/extend.js +19 -19
  167. package/src/utils/private/inject-obj-prop.js +2 -0
  168. package/src/utils/private/rtl.js +10 -7
  169. package/src/utils/run-sequential-promises.js +1 -1
@@ -32,5 +32,58 @@
32
32
  "default": {
33
33
  "desc": "This is where custom content goes, unless 'icon' and 'label' props are not enough"
34
34
  }
35
+ },
36
+
37
+ "events": {
38
+ "click": {
39
+ "desc": "Emitted when the component is clicked",
40
+ "params": {
41
+ "evt": {
42
+ "extends": "evt",
43
+ "desc": "JS event object; If you are using route navigation ('to'/'replace' props) and you want to cancel navigation then call evt.preventDefault() synchronously in your event handler"
44
+ },
45
+ "go": {
46
+ "type": "Function",
47
+ "desc": "Available ONLY if you are using route navigation ('to'/'replace' props); When you need to control the time at which the component should trigger the route navigation then call evt.preventDefault() synchronously and then call this function at your convenience; Useful if you have async work to be done before the actual route navigation or if you want to redirect somewhere else",
48
+ "required": false,
49
+ "addedIn": "v2.9",
50
+ "params": {
51
+ "opts": {
52
+ "type": "Object",
53
+ "desc": "Optional options",
54
+ "required": false,
55
+ "definition": {
56
+ "to": {
57
+ "type": [ "String", "Object" ],
58
+ "desc": "Equivalent to Vue Router <router-link> 'to' property; Specify it explicitly otherwise it will be set with same value as component's 'to' prop",
59
+ "required": false,
60
+ "examples": [
61
+ "/home/dashboard",
62
+ "{ name: 'my-route-name' }"
63
+ ]
64
+ },
65
+
66
+ "replace": {
67
+ "type": "Boolean",
68
+ "desc": "Equivalent to Vue Router <router-link> 'replace' property; Specify it explicitly otherwise it will be set with same value as component's 'replace' prop",
69
+ "required": false
70
+ },
71
+
72
+ "returnRouterError": {
73
+ "type": "Boolean",
74
+ "desc": "Return the router error, if any; Otherwise the returned Promise will always fulfill",
75
+ "required": false
76
+ }
77
+ }
78
+ }
79
+ },
80
+ "returns": {
81
+ "type": "Promise<any>",
82
+ "desc": "Returns the router's navigation promise",
83
+ "__exemption": [ "examples" ]
84
+ }
85
+ }
86
+ }
87
+ }
35
88
  }
36
89
  }
@@ -26,10 +26,12 @@ export default createComponent({
26
26
  ...useBtnProps,
27
27
 
28
28
  percentage: Number,
29
- darkPercentage: Boolean
29
+ darkPercentage: Boolean,
30
+
31
+ onTouchstart: [ Function, Array ]
30
32
  },
31
33
 
32
- emits: [ 'click', 'keydown', 'touchstart', 'mousedown', 'keyup' ],
34
+ emits: [ 'click', 'keydown', 'mousedown', 'keyup' ],
33
35
 
34
36
  setup (props, { slots, emit }) {
35
37
  const { proxy } = getCurrentInstance()
@@ -37,7 +39,7 @@ export default createComponent({
37
39
  const {
38
40
  classes, style, innerClasses,
39
41
  attributes,
40
- hasRouterLink, hasLink, linkTag, navigateToRouterLink,
42
+ hasLink, linkTag, navigateOnClick,
41
43
  isActionable
42
44
  } = useBtn(props)
43
45
 
@@ -72,7 +74,7 @@ export default createComponent({
72
74
  if (props.loading === true) {
73
75
  return {
74
76
  onMousedown: onLoadingEvt,
75
- onTouchstartPassive: onLoadingEvt,
77
+ onTouchstart: onLoadingEvt,
76
78
  onClick: onLoadingEvt,
77
79
  onKeydown: onLoadingEvt,
78
80
  onKeyup: onLoadingEvt
@@ -80,12 +82,21 @@ export default createComponent({
80
82
  }
81
83
 
82
84
  if (isActionable.value === true) {
83
- return {
85
+ const acc = {
84
86
  onClick,
85
87
  onKeydown,
86
- onMousedown,
87
- onTouchstart
88
+ onMousedown
89
+ }
90
+
91
+ if (proxy.$q.platform.has.touch === true) {
92
+ const suffix = props.onTouchstart !== void 0
93
+ ? ''
94
+ : 'Passive'
95
+
96
+ acc[ `onTouchstart${ suffix }` ] = onTouchstart
88
97
  }
98
+
99
+ return acc
89
100
  }
90
101
 
91
102
  return {
@@ -135,18 +146,7 @@ export default createComponent({
135
146
  }
136
147
  }
137
148
 
138
- if (hasRouterLink.value === true) {
139
- const go = () => {
140
- e.__qNavigate = true
141
- navigateToRouterLink(e)
142
- }
143
-
144
- emit('click', e, go)
145
- e.defaultPrevented !== true && go()
146
- }
147
- else {
148
- emit('click', e)
149
- }
149
+ navigateOnClick(e)
150
150
  }
151
151
 
152
152
  function onKeydown (e) {
@@ -49,17 +49,52 @@
49
49
 
50
50
  "events": {
51
51
  "click": {
52
- "desc": "Emitted when component is clicked (activated)",
52
+ "desc": "Emitted when the component is clicked",
53
53
  "params": {
54
54
  "evt": {
55
55
  "extends": "evt",
56
- "desc": "JS event object; If you want to cancel navigation set synchronously 'evt.navigate' to false"
56
+ "desc": "JS event object; If you are using route navigation ('to'/'replace' props) and you want to cancel navigation then call evt.preventDefault() synchronously in your event handler"
57
57
  },
58
- "navigateFn": {
58
+ "go": {
59
59
  "type": "Function",
60
- "desc": "When you need to control the time at which the button should trigger the route navigation then set 'evt.navigate' to false and call this function; Useful if you have async work to be done before the actual route navigation",
61
- "params": null,
62
- "returns": null
60
+ "desc": "Available ONLY if you are using route navigation ('to'/'replace' props); When you need to control the time at which the component should trigger the route navigation then call evt.preventDefault() synchronously and then call this function at your convenience; Useful if you have async work to be done before the actual route navigation or if you want to redirect somewhere else",
61
+ "required": false,
62
+ "addedIn": "v2.9",
63
+ "params": {
64
+ "opts": {
65
+ "type": "Object",
66
+ "desc": "Optional options",
67
+ "required": false,
68
+ "definition": {
69
+ "to": {
70
+ "type": [ "String", "Object" ],
71
+ "desc": "Equivalent to Vue Router <router-link> 'to' property; Specify it explicitly otherwise it will be set with same value as component's 'to' prop",
72
+ "required": false,
73
+ "examples": [
74
+ "/home/dashboard",
75
+ "{ name: 'my-route-name' }"
76
+ ]
77
+ },
78
+
79
+ "replace": {
80
+ "type": "Boolean",
81
+ "desc": "Equivalent to Vue Router <router-link> 'replace' property; Specify it explicitly otherwise it will be set with same value as component's 'replace' prop",
82
+ "required": false
83
+ },
84
+
85
+ "returnRouterError": {
86
+ "type": "Boolean",
87
+ "desc": "Return the router error, if any; Otherwise the returned Promise will always fulfill",
88
+ "required": false
89
+ }
90
+ }
91
+ }
92
+ },
93
+ "returns": {
94
+ "type": "Promise<any>",
95
+ "desc": "Returns the router's navigation promise",
96
+ "__exemption": [ "examples" ]
97
+ }
63
98
  }
64
99
  }
65
100
  }
@@ -80,7 +80,9 @@ export const useBtnProps = {
80
80
  export default function (props) {
81
81
  const sizeStyle = useSize(props, defaultSizes)
82
82
  const alignClass = useAlign(props)
83
- const { hasRouterLink, hasLink, linkTag, linkProps, navigateToRouterLink } = useRouterLink('button')
83
+ const { hasRouterLink, hasLink, linkTag, linkAttrs, navigateOnClick } = useRouterLink({
84
+ fallbackTag: 'button'
85
+ })
84
86
 
85
87
  const style = computed(() => {
86
88
  const obj = props.fab === false && props.fabMini === false
@@ -123,7 +125,7 @@ export default function (props) {
123
125
  const acc = { tabindex: tabIndex.value }
124
126
 
125
127
  if (hasLink.value === true) {
126
- Object.assign(acc, linkProps.value)
128
+ Object.assign(acc, linkAttrs.value)
127
129
  }
128
130
  else if (formTypes.includes(props.type) === true) {
129
131
  acc.type = props.type
@@ -136,6 +138,7 @@ export default function (props) {
136
138
  else if (acc.href === void 0) {
137
139
  acc.role = 'button'
138
140
  }
141
+
139
142
  if (hasRouterLink.value !== true && mediaTypeRE.test(props.type) === true) {
140
143
  acc.type = props.type
141
144
  }
@@ -198,10 +201,9 @@ export default function (props) {
198
201
  style,
199
202
  innerClasses,
200
203
  attributes,
201
- hasRouterLink,
202
204
  hasLink,
203
205
  linkTag,
204
- navigateToRouterLink,
206
+ navigateOnClick,
205
207
  isActionable
206
208
  }
207
209
  }
@@ -125,7 +125,7 @@
125
125
  "type": "String",
126
126
  "desc": "aria-label to be used on the dropdown toggle element",
127
127
  "examples": [ "Open menu" ],
128
- "category": "content",
128
+ "category": "accessibility",
129
129
  "addedIn": "v2.8.4"
130
130
  }
131
131
  },
@@ -11,8 +11,7 @@ const bgNode = h('div', {
11
11
  }, [
12
12
  h('svg', {
13
13
  class: 'q-checkbox__svg fit absolute-full',
14
- viewBox: '0 0 24 24',
15
- 'aria-hidden': 'true'
14
+ viewBox: '0 0 24 24'
16
15
  }, [
17
16
  h('path', {
18
17
  class: 'q-checkbox__truthy',
@@ -211,7 +211,8 @@ export default function (type, getInner) {
211
211
  const child = [
212
212
  h('div', {
213
213
  class: innerClass.value,
214
- style: sizeStyle.value
214
+ style: sizeStyle.value,
215
+ 'aria-hidden': 'true'
215
216
  }, inner)
216
217
  ]
217
218
 
@@ -99,7 +99,7 @@
99
99
  "type": "String",
100
100
  "desc": "aria-label to be used on the remove icon",
101
101
  "examples": [ "Remove item" ],
102
- "category": "content",
102
+ "category": "accessibility",
103
103
  "addedIn": "v2.8.4"
104
104
  },
105
105
 
@@ -94,7 +94,7 @@ export default createComponent({
94
94
  )
95
95
 
96
96
  const { preventBodyScroll } = usePreventScroll()
97
- const { registerTimeout, removeTimeout } = useTimeout()
97
+ const { registerTimeout } = useTimeout()
98
98
  const { registerTick, removeTick } = useTick()
99
99
 
100
100
  const { showPortal, hidePortal, portalIsAccessible, renderPortal } = usePortal(
@@ -179,8 +179,6 @@ export default createComponent({
179
179
  })
180
180
 
181
181
  function handleShow (evt) {
182
- removeTimeout()
183
- removeTick()
184
182
  addToHistory()
185
183
 
186
184
  refocusTarget = props.noRefocus === false && document.activeElement !== null
@@ -195,7 +193,11 @@ export default createComponent({
195
193
  document.activeElement !== null && document.activeElement.blur()
196
194
  registerTick(focus)
197
195
  }
196
+ else {
197
+ removeTick()
198
+ }
198
199
 
200
+ // should removeTimeout() if this gets removed
199
201
  registerTimeout(() => {
200
202
  if (vm.proxy.$q.platform.is.ios === true) {
201
203
  if (props.seamless !== true && document.activeElement) {
@@ -231,7 +233,6 @@ export default createComponent({
231
233
  }
232
234
 
233
235
  function handleHide (evt) {
234
- removeTimeout()
235
236
  removeTick()
236
237
  removeFromHistory()
237
238
  cleanup(true)
@@ -243,6 +244,7 @@ export default createComponent({
243
244
  refocusTarget = null
244
245
  }
245
246
 
247
+ // should removeTimeout() if this gets removed
246
248
  registerTimeout(() => {
247
249
  hidePortal(true) // done hiding, now destroy
248
250
  animating.value = false
@@ -75,7 +75,7 @@ export default createComponent({
75
75
 
76
76
  const isDark = useDark(props, $q)
77
77
  const { preventBodyScroll } = usePreventScroll()
78
- const { registerTimeout } = useTimeout()
78
+ const { registerTimeout, removeTimeout } = useTimeout()
79
79
 
80
80
  const $layout = inject(layoutKey, () => {
81
81
  console.error('QDrawer needs to be child of QLayout')
@@ -145,9 +145,12 @@ export default createComponent({
145
145
 
146
146
  cleanup()
147
147
 
148
- noEvent !== true && registerTimeout(() => {
149
- emit('hide', evt)
150
- }, duration)
148
+ if (noEvent !== true) {
149
+ registerTimeout(() => { emit('hide', evt) }, duration)
150
+ }
151
+ else {
152
+ removeTimeout()
153
+ }
151
154
  }
152
155
 
153
156
  const { show, hide } = useModelToggle({
@@ -312,5 +312,14 @@
312
312
  "__exemption": [ "examples" ]
313
313
  }
314
314
  }
315
+ },
316
+
317
+ "computedProps": {
318
+ "caret": {
319
+ "type": "Object",
320
+ "tsType": "QEditorCaret",
321
+ "desc": "The current caret state",
322
+ "__exemption": [ "examples" ]
323
+ }
315
324
  }
316
325
  }
@@ -37,7 +37,7 @@
37
37
  "type": "String",
38
38
  "desc": "aria-label to be used on the expansion toggle element",
39
39
  "examples": [ "Open details" ],
40
- "category": "content",
40
+ "category": "accessibility",
41
41
  "addedIn": "v2.8.4"
42
42
  },
43
43
 
@@ -41,7 +41,7 @@ export default createComponent({
41
41
  const { proxy: { $q } } = getCurrentInstance()
42
42
 
43
43
  const isDark = useDark(props, $q)
44
- const { hasRouterLink, hasLink, linkProps, linkClass, linkTag, navigateToRouterLink } = useRouterLink()
44
+ const { hasLink, linkAttrs, linkClass, linkTag, navigateOnClick } = useRouterLink()
45
45
 
46
46
  const rootRef = ref(null)
47
47
  const blurTargetRef = ref(null)
@@ -65,7 +65,7 @@ export default createComponent({
65
65
  ? linkClass.value
66
66
  : (
67
67
  props.active === true
68
- ? `${ props.activeClass !== void 0 ? ` ${ props.activeClass }` : '' } q-item--active`
68
+ ? ` q-item--active${ props.activeClass !== void 0 ? ` ${ props.activeClass }` : '' }`
69
69
  : ''
70
70
  )
71
71
  )
@@ -101,8 +101,7 @@ export default createComponent({
101
101
  }
102
102
  }
103
103
 
104
- hasRouterLink.value === true && navigateToRouterLink(e)
105
- emit('click', e)
104
+ navigateOnClick(e)
106
105
  }
107
106
  }
108
107
 
@@ -143,7 +142,7 @@ export default createComponent({
143
142
 
144
143
  if (isClickable.value === true) {
145
144
  data.tabindex = props.tabindex || '0'
146
- Object.assign(data, linkProps.value)
145
+ Object.assign(data, linkAttrs.value)
147
146
  }
148
147
  else if (isActionable.value === true) {
149
148
  data[ 'aria-disabled' ] = 'true'
@@ -62,5 +62,58 @@
62
62
  "default": {
63
63
  "desc": "This is where QItem's content goes"
64
64
  }
65
+ },
66
+
67
+ "events": {
68
+ "click": {
69
+ "desc": "Emitted when the component is clicked",
70
+ "params": {
71
+ "evt": {
72
+ "extends": "evt",
73
+ "desc": "JS event object; If you are using route navigation ('to'/'replace' props) and you want to cancel navigation then call evt.preventDefault() synchronously in your event handler"
74
+ },
75
+ "go": {
76
+ "type": "Function",
77
+ "desc": "Available ONLY if you are using route navigation ('to'/'replace' props); When you need to control the time at which the component should trigger the route navigation then call evt.preventDefault() synchronously and then call this function at your convenience; Useful if you have async work to be done before the actual route navigation or if you want to redirect somewhere else",
78
+ "required": false,
79
+ "addedIn": "v2.9",
80
+ "params": {
81
+ "opts": {
82
+ "type": "Object",
83
+ "desc": "Optional options",
84
+ "required": false,
85
+ "definition": {
86
+ "to": {
87
+ "type": [ "String", "Object" ],
88
+ "desc": "Equivalent to Vue Router <router-link> 'to' property; Specify it explicitly otherwise it will be set with same value as component's 'to' prop",
89
+ "required": false,
90
+ "examples": [
91
+ "/home/dashboard",
92
+ "{ name: 'my-route-name' }"
93
+ ]
94
+ },
95
+
96
+ "replace": {
97
+ "type": "Boolean",
98
+ "desc": "Equivalent to Vue Router <router-link> 'replace' property; Specify it explicitly otherwise it will be set with same value as component's 'replace' prop",
99
+ "required": false
100
+ },
101
+
102
+ "returnRouterError": {
103
+ "type": "Boolean",
104
+ "desc": "Return the router error, if any; Otherwise the returned Promise will always fulfill",
105
+ "required": false
106
+ }
107
+ }
108
+ }
109
+ },
110
+ "returns": {
111
+ "type": "Promise<any>",
112
+ "desc": "Returns the router's navigation promise",
113
+ "__exemption": [ "examples" ]
114
+ }
115
+ }
116
+ }
117
+ }
65
118
  }
66
119
  }
@@ -99,7 +99,7 @@ export default createComponent({
99
99
 
100
100
  const isDark = useDark(props, $q)
101
101
  const { registerTick, removeTick } = useTick()
102
- const { registerTimeout, removeTimeout } = useTimeout()
102
+ const { registerTimeout } = useTimeout()
103
103
  const { transition, transitionStyle } = useTransition(props, showing)
104
104
  const { localScrollTarget, changeScrollEvent, unconfigureScrollTarget } = useScrollTarget(props, configureScrollTarget)
105
105
 
@@ -187,9 +187,6 @@ export default createComponent({
187
187
  }
188
188
 
189
189
  function handleShow (evt) {
190
- removeTick()
191
- removeTimeout()
192
-
193
190
  refocusTarget = props.noRefocus === false
194
191
  ? document.activeElement
195
192
  : null
@@ -221,11 +218,13 @@ export default createComponent({
221
218
  document.activeElement.blur()
222
219
  }
223
220
 
221
+ // should removeTick() if this gets removed
224
222
  registerTick(() => {
225
223
  updatePosition()
226
224
  props.noFocus !== true && focus()
227
225
  })
228
226
 
227
+ // should removeTimeout() if this gets removed
229
228
  registerTimeout(() => {
230
229
  // required in order to avoid the "double-tap needed" issue
231
230
  if ($q.platform.is.ios === true) {
@@ -243,7 +242,6 @@ export default createComponent({
243
242
 
244
243
  function handleHide (evt) {
245
244
  removeTick()
246
- removeTimeout()
247
245
  hidePortal()
248
246
 
249
247
  anchorCleanup(true)
@@ -261,6 +259,7 @@ export default createComponent({
261
259
  refocusTarget = null
262
260
  }
263
261
 
262
+ // should removeTimeout() if this gets removed
264
263
  registerTimeout(() => {
265
264
  hidePortal(true) // done hiding, now destroy
266
265
  emit('hide', evt)
@@ -80,6 +80,7 @@ describe('Menu API', () => {
80
80
  .click()
81
81
  cy.dataCy('menu')
82
82
  .should('exist')
83
+ // eslint-disable-next-line cypress/no-unnecessary-waiting
83
84
  cy.get('body')
84
85
  .click(499, 0)
85
86
  .wait(300) // Await menu animation otherwise it always passes
@@ -98,6 +99,7 @@ describe('Menu API', () => {
98
99
  .click()
99
100
  cy.dataCy('menu')
100
101
  .should('exist')
102
+ // eslint-disable-next-line cypress/no-unnecessary-waiting
101
103
  cy.get('body')
102
104
  .type('{esc}')
103
105
  .wait(300) // Await menu animation otherwise it always passes
@@ -118,6 +120,7 @@ describe('Menu API', () => {
118
120
 
119
121
  cy.dataCy('wrapper')
120
122
  .click()
123
+ // eslint-disable-next-line cypress/no-unnecessary-waiting
121
124
  cy.dataCy('menu')
122
125
  .should('exist')
123
126
  .dataCy('keep-open')
@@ -136,6 +139,7 @@ describe('Menu API', () => {
136
139
 
137
140
  cy.dataCy('wrapper')
138
141
  .click()
142
+ // eslint-disable-next-line cypress/no-unnecessary-waiting
139
143
  cy.dataCy('menu')
140
144
  .should('exist')
141
145
  .dataCy('keep-open')
@@ -161,6 +165,7 @@ describe('Menu API', () => {
161
165
  .focus()
162
166
  .should('have.focus')
163
167
  .click()
168
+ // eslint-disable-next-line cypress/no-unnecessary-waiting
164
169
  cy.dataCy('menu')
165
170
  .should('exist')
166
171
  .should('have.focus')
@@ -183,6 +188,7 @@ describe('Menu API', () => {
183
188
  .focus()
184
189
  .should('have.focus')
185
190
  .click()
191
+ // eslint-disable-next-line cypress/no-unnecessary-waiting
186
192
  cy.dataCy('menu')
187
193
  .should('exist')
188
194
  .should('have.focus')
@@ -529,6 +535,7 @@ describe('Menu API', () => {
529
535
  let bottom = null
530
536
  let left = null
531
537
 
538
+ // eslint-disable-next-line cypress/no-unnecessary-waiting
532
539
  cy.dataCy('wrapper')
533
540
  .click()
534
541
  .wait(300)
@@ -58,16 +58,13 @@ export default createComponent({
58
58
  let validated = false
59
59
 
60
60
  const scope = computed(() => {
61
- const acc = {
61
+ return injectProp({
62
62
  initialValue: initialValue.value,
63
63
  validate: props.validate,
64
64
  set,
65
65
  cancel,
66
66
  updatePosition
67
- }
68
-
69
- injectProp(acc, 'value', () => currentModel.value, val => { currentModel.value = val })
70
- return acc
67
+ }, 'value', () => currentModel.value, val => { currentModel.value = val })
71
68
  })
72
69
 
73
70
  function set () {
@@ -15,8 +15,7 @@ import { hSlot, hMergeSlot } from '../../utils/private/render.js'
15
15
  const svg = h('svg', {
16
16
  key: 'svg',
17
17
  class: 'q-radio__bg absolute non-selectable',
18
- viewBox: '0 0 24 24',
19
- 'aria-hidden': 'true'
18
+ viewBox: '0 0 24 24'
20
19
  }, [
21
20
  h('path', {
22
21
  d: 'M12,22a10,10 0 0 1 -10,-10a10,10 0 0 1 10,-10a10,10 0 0 1 10,10a10,10 0 0 1 -10,10m0,-22a12,12 0 0 0 -12,12a12,12 0 0 0 12,12a12,12 0 0 0 12,-12a12,12 0 0 0 -12,-12'
@@ -161,7 +160,8 @@ export default createComponent({
161
160
  const child = [
162
161
  h('div', {
163
162
  class: innerClass.value,
164
- style: sizeStyle.value
163
+ style: sizeStyle.value,
164
+ 'aria-hidden': 'true'
165
165
  }, content)
166
166
  ]
167
167