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
@@ -5,18 +5,40 @@ import QBtn from '../btn/QBtn.js'
5
5
  import QBtnGroup from '../btn-group/QBtnGroup.js'
6
6
  import QMenu from '../menu/QMenu.js'
7
7
 
8
- import { useBtnProps } from '../btn/use-btn.js'
8
+ import { getBtnDesignAttr, useBtnProps } from '../btn/use-btn.js'
9
+ import { useTransitionProps } from '../../composables/private/use-transition.js'
9
10
 
10
11
  import { createComponent } from '../../utils/private/create.js'
11
12
  import { stop } from '../../utils/event.js'
12
13
  import uid from '../../utils/uid.js'
13
14
  import { hSlot } from '../../utils/private/render.js'
14
15
 
16
+ const btnPropsList = Object.keys(useBtnProps)
17
+
18
+ // let's not duplicate type checking and prop validations
19
+ // so just specify the props here with no type description
20
+ const btnProps = btnPropsList.reduce(
21
+ (acc, key) => (acc[ key ] = {}) && acc,
22
+ {}
23
+ )
24
+
25
+ export const passBtnProps = props => btnPropsList.reduce(
26
+ (acc, key) => {
27
+ const val = props[ key ]
28
+ if (val !== void 0) {
29
+ acc[ key ] = val
30
+ }
31
+ return acc
32
+ },
33
+ {}
34
+ )
35
+
15
36
  export default createComponent({
16
37
  name: 'QBtnDropdown',
17
38
 
18
39
  props: {
19
- ...useBtnProps,
40
+ ...btnProps,
41
+ ...useTransitionProps,
20
42
 
21
43
  modelValue: Boolean,
22
44
  split: Boolean,
@@ -57,7 +79,7 @@ export default createComponent({
57
79
  const menuRef = ref(null)
58
80
  const targetUid = uid()
59
81
 
60
- const attributes = computed(() => {
82
+ const ariaAttrs = computed(() => {
61
83
  const acc = {
62
84
  'aria-expanded': showing.value === true ? 'true' : 'false',
63
85
  'aria-haspopup': 'true',
@@ -85,6 +107,9 @@ export default createComponent({
85
107
  + (props.split === false ? ' q-btn-dropdown__arrow-container' : '')
86
108
  )
87
109
 
110
+ const btnDesignAttr = computed(() => getBtnDesignAttr(props))
111
+ const btnProps = computed(() => passBtnProps(props))
112
+
88
113
  watch(() => props.modelValue, val => {
89
114
  menuRef.value !== null && menuRef.value[ val ? 'show' : 'hide' ]()
90
115
  })
@@ -165,6 +190,9 @@ export default createComponent({
165
190
  self: props.menuSelf,
166
191
  offset: props.menuOffset,
167
192
  separateClosePopup: true,
193
+ transitionShow: props.transitionShow,
194
+ transitionHide: props.transitionHide,
195
+ transitionDuration: props.transitionDuration,
168
196
  onBeforeShow,
169
197
  onShow,
170
198
  onBeforeHide,
@@ -175,11 +203,11 @@ export default createComponent({
175
203
  if (props.split === false) {
176
204
  return h(QBtn, {
177
205
  class: 'q-btn-dropdown q-btn-dropdown--simple',
178
- ...props,
206
+ ...btnProps.value,
207
+ ...ariaAttrs.value,
179
208
  disable: props.disable === true || props.disableMainBtn === true,
180
209
  noWrap: true,
181
210
  round: false,
182
- ...attributes.value,
183
211
  onClick
184
212
  }, {
185
213
  default: () => hSlot(slots.label, []).concat(Arrow),
@@ -189,21 +217,17 @@ export default createComponent({
189
217
 
190
218
  return h(QBtnGroup, {
191
219
  class: 'q-btn-dropdown q-btn-dropdown--split no-wrap q-btn-item',
192
- outline: props.outline,
193
- flat: props.flat,
194
220
  rounded: props.rounded,
195
221
  square: props.square,
196
- push: props.push,
197
- unelevated: props.unelevated,
222
+ ...btnDesignAttr.value,
198
223
  glossy: props.glossy,
199
224
  stretch: props.stretch
200
225
  }, () => [
201
226
  h(QBtn, {
202
227
  class: 'q-btn-dropdown--current',
203
- ...props,
228
+ ...btnProps.value,
204
229
  disable: props.disable === true || props.disableMainBtn === true,
205
230
  noWrap: true,
206
- iconRight: props.iconRight,
207
231
  round: false,
208
232
  onClick: onClickHide
209
233
  }, {
@@ -213,16 +237,15 @@ export default createComponent({
213
237
 
214
238
  h(QBtn, {
215
239
  class: 'q-btn-dropdown__arrow-container q-anchor--skip',
216
- ...attributes.value,
240
+ ...ariaAttrs.value,
241
+ ...btnDesignAttr.value,
217
242
  disable: props.disable === true || props.disableDropdown === true,
218
- outline: props.outline,
219
- flat: props.flat,
220
243
  rounded: props.rounded,
221
- push: props.push,
222
- size: props.size,
223
244
  color: props.color,
224
245
  textColor: props.textColor,
225
246
  dense: props.dense,
247
+ size: props.size,
248
+ padding: props.padding,
226
249
  ripple: props.ripple
227
250
  }, () => Arrow)
228
251
  ])
@@ -1,5 +1,5 @@
1
1
  {
2
- "mixins": [ "components/btn/use-btn", "composables/private/use-model-toggle" ],
2
+ "mixins": [ "components/btn/use-btn", "composables/private/use-model-toggle", "composables/private/use-transition" ],
3
3
 
4
4
  "meta": {
5
5
  "docsUrl": "https://v2.quasar.dev/vue-components/button-dropdown"
@@ -7,6 +7,7 @@ import { createComponent } from '../../utils/private/create.js'
7
7
  import { useFormInject, useFormProps } from '../../composables/private/use-form.js'
8
8
 
9
9
  import { hMergeSlot } from '../../utils/private/render.js'
10
+ import { getBtnDesignAttr } from '../btn/use-btn.js'
10
11
 
11
12
  export default createComponent({
12
13
  name: 'QBtnToggle',
@@ -80,6 +81,14 @@ export default createComponent({
80
81
 
81
82
  const injectFormInput = useFormInject(formAttrs)
82
83
 
84
+ const btnDesignAttr = computed(() => getBtnDesignAttr(props))
85
+
86
+ const btnOptionDesign = computed(() => ({
87
+ rounded: props.rounded,
88
+ dense: props.dense,
89
+ ...btnDesignAttr.value
90
+ }))
91
+
83
92
  const btnOptions = computed(() => props.options.map((item, i) => {
84
93
  const { attrs, value, slot, ...opt } = item
85
94
 
@@ -87,19 +96,11 @@ export default createComponent({
87
96
  slot,
88
97
  props: {
89
98
  key: i,
90
- onClick (e) { set(value, item, e) },
91
99
 
92
100
  'aria-pressed': value === props.modelValue ? 'true' : 'false',
93
-
94
101
  ...attrs,
95
102
  ...opt,
96
-
97
- outline: props.outline,
98
- flat: props.flat,
99
- rounded: props.rounded,
100
- push: props.push,
101
- unelevated: props.unelevated,
102
- dense: props.dense,
103
+ ...btnOptionDesign.value,
103
104
 
104
105
  disable: props.disable === true || opt.disable === true,
105
106
 
@@ -117,7 +118,9 @@ export default createComponent({
117
118
  padding: mergeOpt(opt, 'padding'),
118
119
  ripple: mergeOpt(opt, 'ripple'),
119
120
  stack: mergeOpt(opt, 'stack') === true,
120
- stretch: mergeOpt(opt, 'stretch') === true
121
+ stretch: mergeOpt(opt, 'stretch') === true,
122
+
123
+ onClick (e) { set(value, item, e) }
121
124
  }
122
125
  }
123
126
  }))
@@ -156,12 +159,9 @@ export default createComponent({
156
159
 
157
160
  return () => h(QBtnGroup, {
158
161
  class: 'q-btn-toggle',
159
- outline: props.outline,
160
- flat: props.flat,
162
+ ...btnDesignAttr.value,
161
163
  rounded: props.rounded,
162
- push: props.push,
163
164
  stretch: props.stretch,
164
- unelevated: props.unelevated,
165
165
  glossy: props.glossy,
166
166
  spread: props.spread
167
167
  }, getContent)
@@ -127,7 +127,7 @@ export default function (type, getInner) {
127
127
  const attributes = computed(() => {
128
128
  const attrs = {
129
129
  tabindex: tabindex.value,
130
- role: 'checkbox',
130
+ role: type === 'toggle' ? 'switch' : 'checkbox',
131
131
  'aria-label': props.label,
132
132
  'aria-checked': isIndeterminate.value === true
133
133
  ? 'mixed'
@@ -102,16 +102,19 @@ export default createComponent({
102
102
  + (isDark.value === true ? ' q-chip--dark q-dark' : '')
103
103
  })
104
104
 
105
- const attributes = computed(() => (
106
- props.disable === true
105
+ const attributes = computed(() => {
106
+ const chip = props.disable === true
107
107
  ? { tabindex: -1, 'aria-disabled': 'true' }
108
- : {
109
- tabindex: props.tabindex || 0,
110
- role: 'button',
111
- 'aria-hidden': 'false',
112
- 'aria-label': props.removeAriaLabel || $q.lang.label.remove
113
- }
114
- ))
108
+ : { tabindex: props.tabindex || 0 }
109
+ const remove = {
110
+ ...chip,
111
+ role: 'button',
112
+ 'aria-hidden': 'false',
113
+ 'aria-label': props.removeAriaLabel || $q.lang.label.remove
114
+ }
115
+
116
+ return { chip, remove }
117
+ })
115
118
 
116
119
  function onKeyup (e) {
117
120
  e.keyCode === 13 /* ENTER */ && onClick(e)
@@ -169,7 +172,7 @@ export default createComponent({
169
172
  h(QIcon, {
170
173
  class: 'q-chip__icon q-chip__icon--remove cursor-pointer',
171
174
  name: removeIcon.value,
172
- ...attributes.value,
175
+ ...attributes.value.remove,
173
176
  onClick: onRemove,
174
177
  onKeyup: onRemove
175
178
  })
@@ -188,7 +191,7 @@ export default createComponent({
188
191
 
189
192
  isClickable.value === true && Object.assign(
190
193
  data,
191
- attributes.value,
194
+ attributes.value.chip,
192
195
  { onClick, onKeyup }
193
196
  )
194
197
 
@@ -376,7 +376,8 @@ export default createComponent({
376
376
 
377
377
  function renderPortalContent () {
378
378
  return h('div', {
379
- 'aria-modal': 'true',
379
+ role: 'dialog',
380
+ 'aria-modal': useBackdrop.value === true ? 'true' : 'false',
380
381
  ...attrs,
381
382
  class: rootClasses.value
382
383
  }, [
@@ -70,6 +70,7 @@ export default createComponent({
70
70
  action.class
71
71
  ],
72
72
  tabindex: 0,
73
+ role: 'listitem',
73
74
  onClick () { onOk(action) },
74
75
  onKeyup (e) { e.keyCode === 13 && onOk(action) }
75
76
  }, [
@@ -145,9 +146,12 @@ export default createComponent({
145
146
  child.push(
146
147
  props.grid === true
147
148
  ? h('div', {
148
- class: 'row items-stretch justify-start'
149
+ class: 'row items-stretch justify-start',
150
+ role: 'list'
149
151
  }, getGrid())
150
- : h('div', getList())
152
+ : h('div', {
153
+ role: 'list'
154
+ }, getList())
151
155
  )
152
156
 
153
157
  return child
@@ -11,7 +11,7 @@ import TouchPan from '../../directives/TouchPan.js'
11
11
  import { createComponent } from '../../utils/private/create.js'
12
12
  import { between } from '../../utils/format.js'
13
13
  import { hSlot, hDir } from '../../utils/private/render.js'
14
- import { layoutKey } from '../../utils/private/symbols.js'
14
+ import { layoutKey, emptyRenderFn } from '../../utils/private/symbols.js'
15
15
 
16
16
  const duration = 150
17
17
 
@@ -77,9 +77,11 @@ export default createComponent({
77
77
  const { preventBodyScroll } = usePreventScroll()
78
78
  const { registerTimeout, removeTimeout } = useTimeout()
79
79
 
80
- const $layout = inject(layoutKey, () => {
80
+ const $layout = inject(layoutKey, emptyRenderFn)
81
+ if ($layout === emptyRenderFn) {
81
82
  console.error('QDrawer needs to be child of QLayout')
82
- })
83
+ return emptyRenderFn
84
+ }
83
85
 
84
86
  let lastDesktopState, timerMini, layoutTotalWidthWatcher
85
87
 
@@ -6,7 +6,7 @@ import QResizeObserver from '../resize-observer/QResizeObserver.js'
6
6
 
7
7
  import { createComponent } from '../../utils/private/create.js'
8
8
  import { hMergeSlot } from '../../utils/private/render.js'
9
- import { layoutKey } from '../../utils/private/symbols.js'
9
+ import { layoutKey, emptyRenderFn } from '../../utils/private/symbols.js'
10
10
 
11
11
  export default createComponent({
12
12
  name: 'QFooter',
@@ -31,9 +31,11 @@ export default createComponent({
31
31
  setup (props, { slots, emit }) {
32
32
  const { proxy: { $q } } = getCurrentInstance()
33
33
 
34
- const $layout = inject(layoutKey, () => {
34
+ const $layout = inject(layoutKey, emptyRenderFn)
35
+ if ($layout === emptyRenderFn) {
35
36
  console.error('QFooter needs to be child of QLayout')
36
- })
37
+ return emptyRenderFn
38
+ }
37
39
 
38
40
  const size = ref(parseInt(props.heightHint, 10))
39
41
  const revealed = ref(true)
@@ -4,7 +4,7 @@ import QResizeObserver from '../resize-observer/QResizeObserver.js'
4
4
 
5
5
  import { createComponent } from '../../utils/private/create.js'
6
6
  import { hUniqueSlot } from '../../utils/private/render.js'
7
- import { layoutKey } from '../../utils/private/symbols.js'
7
+ import { layoutKey, emptyRenderFn } from '../../utils/private/symbols.js'
8
8
 
9
9
  export default createComponent({
10
10
  name: 'QHeader',
@@ -33,9 +33,11 @@ export default createComponent({
33
33
  setup (props, { slots, emit }) {
34
34
  const { proxy: { $q } } = getCurrentInstance()
35
35
 
36
- const $layout = inject(layoutKey, () => {
36
+ const $layout = inject(layoutKey, emptyRenderFn)
37
+ if ($layout === emptyRenderFn) {
37
38
  console.error('QHeader needs to be child of QLayout')
38
- })
39
+ return emptyRenderFn
40
+ }
39
41
 
40
42
  const size = ref(parseInt(props.heightHint, 10))
41
43
  const revealed = ref(true)
@@ -166,7 +166,7 @@ export default function (props, emit, emitValue, inputRef) {
166
166
  '^'
167
167
  + unmask.join('')
168
168
  + '(' + (unmaskChar === '' ? '.' : '[^' + unmaskChar + ']') + '+)?'
169
- + '[' + unmaskChar + ']*$'
169
+ + (unmaskChar === '' ? '' : '[' + unmaskChar + ']*') + '$'
170
170
  ),
171
171
  extractLast = extract.length - 1,
172
172
  extractMatcher = extract.map((re, index) => {
@@ -136,6 +136,7 @@ export default createComponent({
136
136
  ref: rootRef,
137
137
  class: classes.value,
138
138
  style: style.value,
139
+ role: 'listitem',
139
140
  onClick,
140
141
  onKeyup
141
142
  }
@@ -29,6 +29,6 @@ export default createComponent({
29
29
  + (props.padding === true ? ' q-list--padding' : '')
30
30
  )
31
31
 
32
- return () => h('div', { class: classes.value }, hSlot(slots.default))
32
+ return () => h('div', { class: classes.value, role: 'list' }, hSlot(slots.default))
33
33
  }
34
34
  })
@@ -74,7 +74,7 @@ export default createComponent({
74
74
  )
75
75
 
76
76
  const attrs = computed(() => {
77
- const attrs = {}
77
+ const attrs = { role: 'group' }
78
78
 
79
79
  if (props.type === 'radio') {
80
80
  attrs.role = 'radiogroup'
@@ -2,7 +2,7 @@ import { h, computed, inject, getCurrentInstance } from 'vue'
2
2
 
3
3
  import { createComponent } from '../../utils/private/create.js'
4
4
  import { hSlot } from '../../utils/private/render.js'
5
- import { pageContainerKey, layoutKey } from '../../utils/private/symbols.js'
5
+ import { pageContainerKey, layoutKey, emptyRenderFn } from '../../utils/private/symbols.js'
6
6
 
7
7
  export default createComponent({
8
8
  name: 'QPage',
@@ -15,10 +15,17 @@ export default createComponent({
15
15
  setup (props, { slots }) {
16
16
  const { proxy: { $q } } = getCurrentInstance()
17
17
 
18
- const $layout = inject(layoutKey)
19
- inject(pageContainerKey, () => {
18
+ const $layout = inject(layoutKey, emptyRenderFn)
19
+ if ($layout === emptyRenderFn) {
20
+ console.error('QPage needs to be a deep child of QLayout')
21
+ return emptyRenderFn
22
+ }
23
+
24
+ const $pageContainer = inject(pageContainerKey, emptyRenderFn)
25
+ if ($pageContainer === emptyRenderFn) {
20
26
  console.error('QPage needs to be child of QPageContainer')
21
- })
27
+ return emptyRenderFn
28
+ }
22
29
 
23
30
  const style = computed(() => {
24
31
  const offset
@@ -2,7 +2,7 @@ import { h, computed, provide, inject, getCurrentInstance } from 'vue'
2
2
 
3
3
  import { createComponent } from '../../utils/private/create.js'
4
4
  import { hSlot } from '../../utils/private/render.js'
5
- import { pageContainerKey, layoutKey } from '../../utils/private/symbols.js'
5
+ import { pageContainerKey, layoutKey, emptyRenderFn } from '../../utils/private/symbols.js'
6
6
 
7
7
  export default createComponent({
8
8
  name: 'QPageContainer',
@@ -10,9 +10,11 @@ export default createComponent({
10
10
  setup (_, { slots }) {
11
11
  const { proxy: { $q } } = getCurrentInstance()
12
12
 
13
- const $layout = inject(layoutKey, () => {
13
+ const $layout = inject(layoutKey, emptyRenderFn)
14
+ if ($layout === emptyRenderFn) {
14
15
  console.error('QPageContainer needs to be child of QLayout')
15
- })
16
+ return emptyRenderFn
17
+ }
16
18
 
17
19
  provide(pageContainerKey, true)
18
20
 
@@ -1,7 +1,7 @@
1
1
  import { h, computed, inject, getCurrentInstance } from 'vue'
2
2
 
3
3
  import { hSlot } from '../../utils/private/render.js'
4
- import { layoutKey } from '../../utils/private/symbols.js'
4
+ import { layoutKey, emptyRenderFn } from '../../utils/private/symbols.js'
5
5
 
6
6
  export const usePageStickyProps = {
7
7
  position: {
@@ -23,9 +23,11 @@ export const usePageStickyProps = {
23
23
  export default function () {
24
24
  const { props, proxy: { $q } } = getCurrentInstance()
25
25
 
26
- const $layout = inject(layoutKey, () => {
26
+ const $layout = inject(layoutKey, emptyRenderFn)
27
+ if ($layout === emptyRenderFn) {
27
28
  console.error('QPageSticky needs to be child of QLayout')
28
- })
29
+ return emptyRenderFn
30
+ }
29
31
 
30
32
  const attach = computed(() => {
31
33
  const pos = props.position