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
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Quasar Framework v2.9.2
2
+ * Quasar Framework v2.10.0
3
3
  * (c) 2015-present Razvan Stoenescu
4
4
  * Released under the MIT License.
5
5
  */
@@ -1398,6 +1398,8 @@
1398
1398
  const tabsKey = '_q_tabs_';
1399
1399
  const uploaderKey = '_q_u_';
1400
1400
 
1401
+ const emptyRenderFn = () => {};
1402
+
1401
1403
  const globalConfig = {};
1402
1404
  let globalConfigIsFrozen = false;
1403
1405
 
@@ -1610,7 +1612,7 @@
1610
1612
  }
1611
1613
 
1612
1614
  var installQuasar = function (parentApp, opts = {}) {
1613
- const $q = { version: '2.9.2' };
1615
+ const $q = { version: '2.10.0' };
1614
1616
 
1615
1617
  if (globalConfigIsFrozen === false) {
1616
1618
  if (opts.config !== void 0) {
@@ -2369,7 +2371,7 @@
2369
2371
  return () => vue.h('div', {
2370
2372
  class: classes.value,
2371
2373
  style: style.value,
2372
- role: 'alert',
2374
+ role: 'status',
2373
2375
  'aria-label': props.label
2374
2376
  }, hMergeSlot(slots.default, props.label !== void 0 ? [ props.label ] : []))
2375
2377
  }
@@ -3300,7 +3302,7 @@
3300
3302
  }
3301
3303
  );
3302
3304
 
3303
- const padding = {
3305
+ const btnPadding = {
3304
3306
  none: 0,
3305
3307
  xs: 4,
3306
3308
  sm: 8,
@@ -3320,6 +3322,21 @@
3320
3322
  const formTypes = [ 'button', 'submit', 'reset' ];
3321
3323
  const mediaTypeRE = /[^\s]\/[^\s]/;
3322
3324
 
3325
+ const btnDesignOptions = [ 'flat', 'outline', 'push', 'unelevated' ];
3326
+ const getBtnDesign = (props, defaultValue) => {
3327
+ if (props.flat === true) return 'flat'
3328
+ if (props.outline === true) return 'outline'
3329
+ if (props.push === true) return 'push'
3330
+ if (props.unelevated === true) return 'unelevated'
3331
+ return defaultValue
3332
+ };
3333
+ const getBtnDesignAttr = props => {
3334
+ const design = getBtnDesign(props);
3335
+ return design !== void 0
3336
+ ? { [ design ]: true }
3337
+ : {}
3338
+ };
3339
+
3323
3340
  const useBtnProps = {
3324
3341
  ...useSizeProps,
3325
3342
  ...useRouterLinkProps,
@@ -3333,13 +3350,14 @@
3333
3350
  icon: String,
3334
3351
  iconRight: String,
3335
3352
 
3336
- round: Boolean,
3353
+ ...btnDesignOptions.reduce(
3354
+ (acc, val) => (acc[ val ] = Boolean) && acc,
3355
+ {}
3356
+ ),
3357
+
3337
3358
  square: Boolean,
3338
- outline: Boolean,
3339
- flat: Boolean,
3340
- unelevated: Boolean,
3359
+ round: Boolean,
3341
3360
  rounded: Boolean,
3342
- push: Boolean,
3343
3361
  glossy: Boolean,
3344
3362
 
3345
3363
  size: String,
@@ -3389,7 +3407,7 @@
3389
3407
  ? Object.assign({}, obj, {
3390
3408
  padding: props.padding
3391
3409
  .split(/\s+/)
3392
- .map(v => (v in padding ? padding[ v ] + 'px' : v))
3410
+ .map(v => (v in btnPadding ? btnPadding[ v ] + 'px' : v))
3393
3411
  .join(' '),
3394
3412
  minWidth: '0',
3395
3413
  minHeight: '0'
@@ -3409,13 +3427,7 @@
3409
3427
  isActionable.value === true ? props.tabindex || 0 : -1
3410
3428
  ));
3411
3429
 
3412
- const design = vue.computed(() => {
3413
- if (props.flat === true) return 'flat'
3414
- if (props.outline === true) return 'outline'
3415
- if (props.push === true) return 'push'
3416
- if (props.unelevated === true) return 'unelevated'
3417
- return 'standard'
3418
- });
3430
+ const design = vue.computed(() => getBtnDesign(props, 'standard'));
3419
3431
 
3420
3432
  const attributes = vue.computed(() => {
3421
3433
  const acc = { tabindex: tabIndex.value };
@@ -5667,11 +5679,32 @@
5667
5679
  + hexBytes[ b[ 14 ] ] + hexBytes[ b[ 15 ] ]
5668
5680
  }
5669
5681
 
5682
+ const btnPropsList = Object.keys(useBtnProps);
5683
+
5684
+ // let's not duplicate type checking and prop validations
5685
+ // so just specify the props here with no type description
5686
+ const btnProps = btnPropsList.reduce(
5687
+ (acc, key) => (acc[ key ] = {}) && acc,
5688
+ {}
5689
+ );
5690
+
5691
+ const passBtnProps = props => btnPropsList.reduce(
5692
+ (acc, key) => {
5693
+ const val = props[ key ];
5694
+ if (val !== void 0) {
5695
+ acc[ key ] = val;
5696
+ }
5697
+ return acc
5698
+ },
5699
+ {}
5700
+ );
5701
+
5670
5702
  var QBtnDropdown = createComponent({
5671
5703
  name: 'QBtnDropdown',
5672
5704
 
5673
5705
  props: {
5674
- ...useBtnProps,
5706
+ ...btnProps,
5707
+ ...useTransitionProps,
5675
5708
 
5676
5709
  modelValue: Boolean,
5677
5710
  split: Boolean,
@@ -5712,7 +5745,7 @@
5712
5745
  const menuRef = vue.ref(null);
5713
5746
  const targetUid = uid$3();
5714
5747
 
5715
- const attributes = vue.computed(() => {
5748
+ const ariaAttrs = vue.computed(() => {
5716
5749
  const acc = {
5717
5750
  'aria-expanded': showing.value === true ? 'true' : 'false',
5718
5751
  'aria-haspopup': 'true',
@@ -5740,6 +5773,9 @@
5740
5773
  + (props.split === false ? ' q-btn-dropdown__arrow-container' : '')
5741
5774
  );
5742
5775
 
5776
+ const btnDesignAttr = vue.computed(() => getBtnDesignAttr(props));
5777
+ const btnProps = vue.computed(() => passBtnProps(props));
5778
+
5743
5779
  vue.watch(() => props.modelValue, val => {
5744
5780
  menuRef.value !== null && menuRef.value[ val ? 'show' : 'hide' ]();
5745
5781
  });
@@ -5820,6 +5856,9 @@
5820
5856
  self: props.menuSelf,
5821
5857
  offset: props.menuOffset,
5822
5858
  separateClosePopup: true,
5859
+ transitionShow: props.transitionShow,
5860
+ transitionHide: props.transitionHide,
5861
+ transitionDuration: props.transitionDuration,
5823
5862
  onBeforeShow,
5824
5863
  onShow,
5825
5864
  onBeforeHide,
@@ -5830,11 +5869,11 @@
5830
5869
  if (props.split === false) {
5831
5870
  return vue.h(QBtn, {
5832
5871
  class: 'q-btn-dropdown q-btn-dropdown--simple',
5833
- ...props,
5872
+ ...btnProps.value,
5873
+ ...ariaAttrs.value,
5834
5874
  disable: props.disable === true || props.disableMainBtn === true,
5835
5875
  noWrap: true,
5836
5876
  round: false,
5837
- ...attributes.value,
5838
5877
  onClick
5839
5878
  }, {
5840
5879
  default: () => hSlot(slots.label, []).concat(Arrow),
@@ -5844,21 +5883,17 @@
5844
5883
 
5845
5884
  return vue.h(QBtnGroup, {
5846
5885
  class: 'q-btn-dropdown q-btn-dropdown--split no-wrap q-btn-item',
5847
- outline: props.outline,
5848
- flat: props.flat,
5849
5886
  rounded: props.rounded,
5850
5887
  square: props.square,
5851
- push: props.push,
5852
- unelevated: props.unelevated,
5888
+ ...btnDesignAttr.value,
5853
5889
  glossy: props.glossy,
5854
5890
  stretch: props.stretch
5855
5891
  }, () => [
5856
5892
  vue.h(QBtn, {
5857
5893
  class: 'q-btn-dropdown--current',
5858
- ...props,
5894
+ ...btnProps.value,
5859
5895
  disable: props.disable === true || props.disableMainBtn === true,
5860
5896
  noWrap: true,
5861
- iconRight: props.iconRight,
5862
5897
  round: false,
5863
5898
  onClick: onClickHide
5864
5899
  }, {
@@ -5868,16 +5903,15 @@
5868
5903
 
5869
5904
  vue.h(QBtn, {
5870
5905
  class: 'q-btn-dropdown__arrow-container q-anchor--skip',
5871
- ...attributes.value,
5906
+ ...ariaAttrs.value,
5907
+ ...btnDesignAttr.value,
5872
5908
  disable: props.disable === true || props.disableDropdown === true,
5873
- outline: props.outline,
5874
- flat: props.flat,
5875
5909
  rounded: props.rounded,
5876
- push: props.push,
5877
- size: props.size,
5878
5910
  color: props.color,
5879
5911
  textColor: props.textColor,
5880
5912
  dense: props.dense,
5913
+ size: props.size,
5914
+ padding: props.padding,
5881
5915
  ripple: props.ripple
5882
5916
  }, () => Arrow)
5883
5917
  ])
@@ -5984,6 +6018,14 @@
5984
6018
 
5985
6019
  const injectFormInput = useFormInject(formAttrs);
5986
6020
 
6021
+ const btnDesignAttr = vue.computed(() => getBtnDesignAttr(props));
6022
+
6023
+ const btnOptionDesign = vue.computed(() => ({
6024
+ rounded: props.rounded,
6025
+ dense: props.dense,
6026
+ ...btnDesignAttr.value
6027
+ }));
6028
+
5987
6029
  const btnOptions = vue.computed(() => props.options.map((item, i) => {
5988
6030
  const { attrs, value, slot, ...opt } = item;
5989
6031
 
@@ -5991,19 +6033,11 @@
5991
6033
  slot,
5992
6034
  props: {
5993
6035
  key: i,
5994
- onClick (e) { set(value, item, e); },
5995
6036
 
5996
6037
  'aria-pressed': value === props.modelValue ? 'true' : 'false',
5997
-
5998
6038
  ...attrs,
5999
6039
  ...opt,
6000
-
6001
- outline: props.outline,
6002
- flat: props.flat,
6003
- rounded: props.rounded,
6004
- push: props.push,
6005
- unelevated: props.unelevated,
6006
- dense: props.dense,
6040
+ ...btnOptionDesign.value,
6007
6041
 
6008
6042
  disable: props.disable === true || opt.disable === true,
6009
6043
 
@@ -6021,7 +6055,9 @@
6021
6055
  padding: mergeOpt(opt, 'padding'),
6022
6056
  ripple: mergeOpt(opt, 'ripple'),
6023
6057
  stack: mergeOpt(opt, 'stack') === true,
6024
- stretch: mergeOpt(opt, 'stretch') === true
6058
+ stretch: mergeOpt(opt, 'stretch') === true,
6059
+
6060
+ onClick (e) { set(value, item, e); }
6025
6061
  }
6026
6062
  }
6027
6063
  }));
@@ -6060,12 +6096,9 @@
6060
6096
 
6061
6097
  return () => vue.h(QBtnGroup, {
6062
6098
  class: 'q-btn-toggle',
6063
- outline: props.outline,
6064
- flat: props.flat,
6099
+ ...btnDesignAttr.value,
6065
6100
  rounded: props.rounded,
6066
- push: props.push,
6067
6101
  stretch: props.stretch,
6068
- unelevated: props.unelevated,
6069
6102
  glossy: props.glossy,
6070
6103
  spread: props.spread
6071
6104
  }, getContent)
@@ -7506,7 +7539,7 @@
7506
7539
  const attributes = vue.computed(() => {
7507
7540
  const attrs = {
7508
7541
  tabindex: tabindex.value,
7509
- role: 'checkbox',
7542
+ role: type === 'toggle' ? 'switch' : 'checkbox',
7510
7543
  'aria-label': props.label,
7511
7544
  'aria-checked': isIndeterminate.value === true
7512
7545
  ? 'mixed'
@@ -7771,16 +7804,19 @@
7771
7804
  + (isDark.value === true ? ' q-chip--dark q-dark' : '')
7772
7805
  });
7773
7806
 
7774
- const attributes = vue.computed(() => (
7775
- props.disable === true
7807
+ const attributes = vue.computed(() => {
7808
+ const chip = props.disable === true
7776
7809
  ? { tabindex: -1, 'aria-disabled': 'true' }
7777
- : {
7778
- tabindex: props.tabindex || 0,
7779
- role: 'button',
7780
- 'aria-hidden': 'false',
7781
- 'aria-label': props.removeAriaLabel || $q.lang.label.remove
7782
- }
7783
- ));
7810
+ : { tabindex: props.tabindex || 0 };
7811
+ const remove = {
7812
+ ...chip,
7813
+ role: 'button',
7814
+ 'aria-hidden': 'false',
7815
+ 'aria-label': props.removeAriaLabel || $q.lang.label.remove
7816
+ };
7817
+
7818
+ return { chip, remove }
7819
+ });
7784
7820
 
7785
7821
  function onKeyup (e) {
7786
7822
  e.keyCode === 13 /* ENTER */ && onClick(e);
@@ -7838,7 +7874,7 @@
7838
7874
  vue.h(QIcon, {
7839
7875
  class: 'q-chip__icon q-chip__icon--remove cursor-pointer',
7840
7876
  name: removeIcon.value,
7841
- ...attributes.value,
7877
+ ...attributes.value.remove,
7842
7878
  onClick: onRemove,
7843
7879
  onKeyup: onRemove
7844
7880
  })
@@ -7857,7 +7893,7 @@
7857
7893
 
7858
7894
  isClickable.value === true && Object.assign(
7859
7895
  data,
7860
- attributes.value,
7896
+ attributes.value.chip,
7861
7897
  { onClick, onKeyup }
7862
7898
  );
7863
7899
 
@@ -9341,17 +9377,21 @@
9341
9377
  if (hasObserver === true) {
9342
9378
  let observer;
9343
9379
 
9344
- vue.onMounted(() => {
9345
- vue.nextTick(() => {
9346
- targetEl = proxy.$el.parentNode;
9380
+ // initialize as soon as possible
9381
+ const init = stop => {
9382
+ targetEl = proxy.$el.parentNode;
9347
9383
 
9348
- if (targetEl) {
9349
- observer = new ResizeObserver(trigger);
9350
- observer.observe(targetEl);
9351
- emitEvent();
9352
- }
9353
- });
9354
- });
9384
+ if (targetEl) {
9385
+ observer = new ResizeObserver(trigger);
9386
+ observer.observe(targetEl);
9387
+ emitEvent();
9388
+ }
9389
+ else if (stop !== true) {
9390
+ vue.nextTick(() => { init(true); });
9391
+ }
9392
+ };
9393
+
9394
+ vue.onMounted(() => { init(); });
9355
9395
 
9356
9396
  vue.onBeforeUnmount(() => {
9357
9397
  clearTimeout(timer);
@@ -10035,13 +10075,6 @@
10035
10075
  }
10036
10076
  }
10037
10077
 
10038
- /*
10039
- * Vue has an aggressive diff (in-place replacement) so we cannot
10040
- * ensure that the instance getting destroyed is the actual tab
10041
- * reported here. As a result, we cannot use its name or check
10042
- * if it's a route one to make the necessary updates. We need to
10043
- * always check the existing list again and infer the changes.
10044
- */
10045
10078
  function unregisterTab (tabData) {
10046
10079
  tabDataList.splice(tabDataList.indexOf(tabData), 1);
10047
10080
  tabDataListLen.value--;
@@ -10173,9 +10206,11 @@
10173
10206
  };
10174
10207
 
10175
10208
  function useTab (props, slots, emit, routeData) {
10176
- const $tabs = vue.inject(tabsKey, () => {
10209
+ const $tabs = vue.inject(tabsKey, emptyRenderFn);
10210
+ if ($tabs === emptyRenderFn) {
10177
10211
  console.error('QTab/QRouteTab component needs to be child of QTabs');
10178
- });
10212
+ return emptyRenderFn
10213
+ }
10179
10214
 
10180
10215
  const { proxy } = vue.getCurrentInstance();
10181
10216
 
@@ -10451,7 +10486,7 @@
10451
10486
  props: usePanelChildProps,
10452
10487
 
10453
10488
  setup (_, { slots }) {
10454
- return () => vue.h('div', { class: 'q-tab-panel' }, hSlot(slots.default))
10489
+ return () => vue.h('div', { class: 'q-tab-panel', role: 'tabpanel' }, hSlot(slots.default))
10455
10490
  }
10456
10491
  });
10457
10492
 
@@ -15031,7 +15066,8 @@
15031
15066
 
15032
15067
  function renderPortalContent () {
15033
15068
  return vue.h('div', {
15034
- 'aria-modal': 'true',
15069
+ role: 'dialog',
15070
+ 'aria-modal': useBackdrop.value === true ? 'true' : 'false',
15035
15071
  ...attrs,
15036
15072
  class: rootClasses.value
15037
15073
  }, [
@@ -15135,9 +15171,11 @@
15135
15171
  const { preventBodyScroll } = usePreventScroll();
15136
15172
  const { registerTimeout, removeTimeout } = useTimeout();
15137
15173
 
15138
- const $layout = vue.inject(layoutKey, () => {
15174
+ const $layout = vue.inject(layoutKey, emptyRenderFn);
15175
+ if ($layout === emptyRenderFn) {
15139
15176
  console.error('QDrawer needs to be child of QLayout');
15140
- });
15177
+ return emptyRenderFn
15178
+ }
15141
15179
 
15142
15180
  let lastDesktopState, timerMini, layoutTotalWidthWatcher;
15143
15181
 
@@ -16389,7 +16427,7 @@
16389
16427
  attrs.style,
16390
16428
  transitionStyle.value
16391
16429
  ],
16392
- role: 'complementary'
16430
+ role: 'tooltip'
16393
16431
  }, hSlot(slots.default))
16394
16432
  : null
16395
16433
  }
@@ -16538,6 +16576,7 @@
16538
16576
  ref: rootRef,
16539
16577
  class: classes.value,
16540
16578
  style: style.value,
16579
+ role: 'listitem',
16541
16580
  onClick,
16542
16581
  onKeyup
16543
16582
  };
@@ -19442,7 +19481,14 @@
19442
19481
 
19443
19482
  function onDragleave (e) {
19444
19483
  stopAndPrevent(e);
19445
- e.relatedTarget !== dndRef.value && (dnd.value = false);
19484
+
19485
+ // Safari bug: relatedTarget is null for over 10 years
19486
+ // https://bugs.webkit.org/show_bug.cgi?id=66547
19487
+ const gone = e.relatedTarget !== null || client.is.safari !== true
19488
+ ? e.relatedTarget !== dndRef.value
19489
+ : document.elementsFromPoint(e.clientX, e.clientY).includes(dndRef.value) === false;
19490
+
19491
+ gone === true && (dnd.value = false);
19446
19492
  }
19447
19493
 
19448
19494
  function onDrop (e) {
@@ -19476,6 +19522,7 @@
19476
19522
  pickFiles,
19477
19523
  addFiles,
19478
19524
  onDragover,
19525
+ onDragleave,
19479
19526
  processFiles,
19480
19527
  getDndNode,
19481
19528
 
@@ -19829,9 +19876,11 @@
19829
19876
  setup (props, { slots, emit }) {
19830
19877
  const { proxy: { $q } } = vue.getCurrentInstance();
19831
19878
 
19832
- const $layout = vue.inject(layoutKey, () => {
19879
+ const $layout = vue.inject(layoutKey, emptyRenderFn);
19880
+ if ($layout === emptyRenderFn) {
19833
19881
  console.error('QFooter needs to be child of QLayout');
19834
- });
19882
+ return emptyRenderFn
19883
+ }
19835
19884
 
19836
19885
  const size = vue.ref(parseInt(props.heightHint, 10));
19837
19886
  const revealed = vue.ref(true);
@@ -20249,9 +20298,11 @@
20249
20298
  setup (props, { slots, emit }) {
20250
20299
  const { proxy: { $q } } = vue.getCurrentInstance();
20251
20300
 
20252
- const $layout = vue.inject(layoutKey, () => {
20301
+ const $layout = vue.inject(layoutKey, emptyRenderFn);
20302
+ if ($layout === emptyRenderFn) {
20253
20303
  console.error('QHeader needs to be child of QLayout');
20254
- });
20304
+ return emptyRenderFn
20305
+ }
20255
20306
 
20256
20307
  const size = vue.ref(parseInt(props.heightHint, 10));
20257
20308
  const revealed = vue.ref(true);
@@ -21155,7 +21206,7 @@
21155
21206
  '^'
21156
21207
  + unmask.join('')
21157
21208
  + '(' + (unmaskChar === '' ? '.' : '[^' + unmaskChar + ']') + '+)?'
21158
- + '[' + unmaskChar + ']*$'
21209
+ + (unmaskChar === '' ? '' : '[' + unmaskChar + ']*') + '$'
21159
21210
  ),
21160
21211
  extractLast = extract.length - 1,
21161
21212
  extractMatcher = extract.map((re, index) => {
@@ -22181,7 +22232,7 @@
22181
22232
  + (props.padding === true ? ' q-list--padding' : '')
22182
22233
  );
22183
22234
 
22184
- return () => vue.h('div', { class: classes.value }, hSlot(slots.default))
22235
+ return () => vue.h('div', { class: classes.value, role: 'list' }, hSlot(slots.default))
22185
22236
  }
22186
22237
  });
22187
22238
 
@@ -23222,7 +23273,7 @@
23222
23273
  );
23223
23274
 
23224
23275
  const attrs = vue.computed(() => {
23225
- const attrs = {};
23276
+ const attrs = { role: 'group' };
23226
23277
 
23227
23278
  if (props.type === 'radio') {
23228
23279
  attrs.role = 'radiogroup';
@@ -23287,10 +23338,17 @@
23287
23338
  setup (props, { slots }) {
23288
23339
  const { proxy: { $q } } = vue.getCurrentInstance();
23289
23340
 
23290
- const $layout = vue.inject(layoutKey);
23291
- vue.inject(pageContainerKey, () => {
23341
+ const $layout = vue.inject(layoutKey, emptyRenderFn);
23342
+ if ($layout === emptyRenderFn) {
23343
+ console.error('QPage needs to be a deep child of QLayout');
23344
+ return emptyRenderFn
23345
+ }
23346
+
23347
+ const $pageContainer = vue.inject(pageContainerKey, emptyRenderFn);
23348
+ if ($pageContainer === emptyRenderFn) {
23292
23349
  console.error('QPage needs to be child of QPageContainer');
23293
- });
23350
+ return emptyRenderFn
23351
+ }
23294
23352
 
23295
23353
  const style = vue.computed(() => {
23296
23354
  const offset
@@ -23333,9 +23391,11 @@
23333
23391
  setup (_, { slots }) {
23334
23392
  const { proxy: { $q } } = vue.getCurrentInstance();
23335
23393
 
23336
- const $layout = vue.inject(layoutKey, () => {
23394
+ const $layout = vue.inject(layoutKey, emptyRenderFn);
23395
+ if ($layout === emptyRenderFn) {
23337
23396
  console.error('QPageContainer needs to be child of QLayout');
23338
- });
23397
+ return emptyRenderFn
23398
+ }
23339
23399
 
23340
23400
  vue.provide(pageContainerKey, true);
23341
23401
 
@@ -23385,9 +23445,11 @@
23385
23445
  function usePageSticky () {
23386
23446
  const { props, proxy: { $q } } = vue.getCurrentInstance();
23387
23447
 
23388
- const $layout = vue.inject(layoutKey, () => {
23448
+ const $layout = vue.inject(layoutKey, emptyRenderFn);
23449
+ if ($layout === emptyRenderFn) {
23389
23450
  console.error('QPageSticky needs to be child of QLayout');
23390
- });
23451
+ return emptyRenderFn
23452
+ }
23391
23453
 
23392
23454
  const attach = vue.computed(() => {
23393
23455
  const pos = props.position;
@@ -23600,6 +23662,12 @@
23600
23662
  }
23601
23663
  });
23602
23664
 
23665
+ function getBool (val, otherwise) {
23666
+ return [ true, false ].includes(val)
23667
+ ? val
23668
+ : otherwise
23669
+ }
23670
+
23603
23671
  var QPagination = createComponent({
23604
23672
  name: 'QPagination',
23605
23673
 
@@ -23611,22 +23679,20 @@
23611
23679
  required: true
23612
23680
  },
23613
23681
  min: {
23614
- type: Number,
23682
+ type: [ Number, String ],
23615
23683
  default: 1
23616
23684
  },
23617
23685
  max: {
23618
- type: Number,
23686
+ type: [ Number, String ],
23619
23687
  required: true
23620
23688
  },
23621
-
23622
- color: {
23623
- type: String,
23624
- default: 'primary'
23689
+ maxPages: {
23690
+ type: [ Number, String ],
23691
+ default: 0,
23692
+ validator: v => (
23693
+ (typeof v === 'string' ? parseInt(v, 10) : v) >= 0
23694
+ )
23625
23695
  },
23626
- textColor: String,
23627
-
23628
- activeColor: String,
23629
- activeTextColor: String,
23630
23696
 
23631
23697
  inputStyle: [ Array, String, Object ],
23632
23698
  inputClass: [ Array, String, Object ],
@@ -23660,11 +23726,6 @@
23660
23726
  type: Boolean,
23661
23727
  default: null
23662
23728
  },
23663
- maxPages: {
23664
- type: Number,
23665
- default: 0,
23666
- validator: v => v >= 0
23667
- },
23668
23729
 
23669
23730
  ripple: {
23670
23731
  type: [ Boolean, Object ],
@@ -23680,7 +23741,21 @@
23680
23741
  push: Boolean,
23681
23742
  glossy: Boolean,
23682
23743
 
23683
- dense: Boolean,
23744
+ color: {
23745
+ type: String,
23746
+ default: 'primary'
23747
+ },
23748
+ textColor: String,
23749
+
23750
+ activeDesign: {
23751
+ type: String,
23752
+ default: '',
23753
+ values: v => v === '' || btnDesignOptions.includes(v)
23754
+ },
23755
+ activeColor: String,
23756
+ activeTextColor: String,
23757
+
23758
+ gutter: String,
23684
23759
  padding: {
23685
23760
  type: String,
23686
23761
  default: '3px 2px'
@@ -23695,6 +23770,16 @@
23695
23770
 
23696
23771
  const isDark = useDark(props, $q);
23697
23772
 
23773
+ const minProp = vue.computed(() => parseInt(props.min, 10));
23774
+ const maxProp = vue.computed(() => parseInt(props.max, 10));
23775
+ const maxPagesProp = vue.computed(() => parseInt(props.maxPages, 10));
23776
+
23777
+ const inputPlaceholder = vue.computed(() => model.value + ' / ' + maxProp.value);
23778
+ const boundaryLinksProp = vue.computed(() => getBool(props.boundaryLinks, props.input));
23779
+ const boundaryNumbersProp = vue.computed(() => getBool(props.boundaryNumbers, !props.input));
23780
+ const directionLinksProp = vue.computed(() => getBool(props.directionLinks, props.input));
23781
+ const ellipsesProp = vue.computed(() => getBool(props.ellipses, !props.input));
23782
+
23698
23783
  const newPage = vue.ref(null);
23699
23784
  const model = vue.computed({
23700
23785
  get: () => props.modelValue,
@@ -23703,32 +23788,33 @@
23703
23788
  if (props.disable || isNaN(val)) {
23704
23789
  return
23705
23790
  }
23706
- const value = between(val, props.min, props.max);
23791
+ const value = between(val, minProp.value, maxProp.value);
23707
23792
  if (props.modelValue !== value) {
23708
23793
  emit('update:modelValue', value);
23709
23794
  }
23710
23795
  }
23711
23796
  });
23712
23797
 
23713
- vue.watch(() => props.min + props.max, () => {
23798
+ vue.watch(() => `${ minProp.value }|${ maxProp.value }`, () => {
23714
23799
  model.value = props.modelValue;
23715
23800
  });
23716
23801
 
23717
- function getBool (val, otherwise) {
23718
- return [ true, false ].includes(val)
23719
- ? val
23720
- : otherwise
23721
- }
23722
-
23723
23802
  const classes = vue.computed(() =>
23724
23803
  'q-pagination row no-wrap items-center'
23725
23804
  + (props.disable === true ? ' disabled' : '')
23726
23805
  );
23727
- const inputPlaceholder = vue.computed(() => model.value + ' / ' + props.max);
23728
- const __boundaryLinks = vue.computed(() => getBool(props.boundaryLinks, props.input));
23729
- const __boundaryNumbers = vue.computed(() => getBool(props.boundaryNumbers, !props.input));
23730
- const __directionLinks = vue.computed(() => getBool(props.directionLinks, props.input));
23731
- const __ellipses = vue.computed(() => getBool(props.ellipses, !props.input));
23806
+
23807
+ const gutterProp = vue.computed(() => (
23808
+ props.gutter in btnPadding
23809
+ ? `${ btnPadding[ props.gutter ] }px`
23810
+ : props.gutter || null
23811
+ ));
23812
+ const gutterStyle = vue.computed(() => (
23813
+ gutterProp.value !== null
23814
+ ? `--q-pagination-gutter-parent:-${ gutterProp.value };--q-pagination-gutter-child:${ gutterProp.value }`
23815
+ : null
23816
+ ));
23817
+
23732
23818
  const icons = vue.computed(() => {
23733
23819
  const ico = [
23734
23820
  props.iconFirst || $q.iconSet.pagination.first,
@@ -23739,38 +23825,90 @@
23739
23825
  return $q.lang.rtl === true ? ico.reverse() : ico
23740
23826
  });
23741
23827
 
23742
- const attrs = vue.computed(() => (
23743
- props.disable === true
23744
- ? { 'aria-disabled': 'true' }
23745
- : {}
23746
- ));
23828
+ const attrs = vue.computed(() => ({
23829
+ 'aria-disabled': props.disable === true ? 'true' : 'false',
23830
+ role: 'navigation'
23831
+ }));
23747
23832
 
23833
+ const btnDesignProp = vue.computed(() => getBtnDesign(props, 'flat'));
23748
23834
  const btnProps = vue.computed(() => ({
23835
+ [ btnDesignProp.value ]: true,
23836
+
23749
23837
  round: props.round,
23750
23838
  rounded: props.rounded,
23751
23839
 
23752
- outline: props.outline,
23753
- unelevated: props.unelevated,
23754
- push: props.push,
23755
- glossy: props.glossy,
23756
-
23757
- dense: props.dense,
23758
23840
  padding: props.padding,
23759
23841
 
23760
23842
  color: props.color,
23761
- flat: true,
23843
+ textColor: props.textColor,
23844
+
23762
23845
  size: props.size,
23763
23846
  ripple: props.ripple !== null
23764
23847
  ? props.ripple
23765
23848
  : true
23766
23849
  }));
23767
23850
 
23851
+ const btnActiveDesignProp = vue.computed(() => {
23852
+ // we also reset non-active design
23853
+ const acc = { [ btnDesignProp.value ]: false };
23854
+ if (props.activeDesign !== '') {
23855
+ acc[ props.activeDesign ] = true;
23856
+ }
23857
+ return acc
23858
+ });
23768
23859
  const activeBtnProps = vue.computed(() => ({
23769
- flat: props.flat,
23860
+ ...btnActiveDesignProp.value,
23770
23861
  color: props.activeColor || props.color,
23771
23862
  textColor: props.activeTextColor || props.textColor
23772
23863
  }));
23773
23864
 
23865
+ const btnConfig = vue.computed(() => {
23866
+ let maxPages = Math.max(
23867
+ maxPagesProp.value,
23868
+ 1 + (ellipsesProp.value ? 2 : 0) + (boundaryNumbersProp.value ? 2 : 0)
23869
+ );
23870
+
23871
+ const acc = {
23872
+ pgFrom: minProp.value,
23873
+ pgTo: maxProp.value,
23874
+ ellipsesStart: false,
23875
+ ellipsesEnd: false,
23876
+ boundaryStart: false,
23877
+ boundaryEnd: false,
23878
+ marginalStyle: {
23879
+ minWidth: `${ Math.max(2, String(maxProp.value).length) }em`
23880
+ }
23881
+ };
23882
+
23883
+ if (maxPagesProp.value && maxPages < (maxProp.value - minProp.value + 1)) {
23884
+ maxPages = 1 + Math.floor(maxPages / 2) * 2;
23885
+ acc.pgFrom = Math.max(minProp.value, Math.min(maxProp.value - maxPages + 1, props.modelValue - Math.floor(maxPages / 2)));
23886
+ acc.pgTo = Math.min(maxProp.value, acc.pgFrom + maxPages - 1);
23887
+
23888
+ if (boundaryNumbersProp.value) {
23889
+ acc.boundaryStart = true;
23890
+ acc.pgFrom++;
23891
+ }
23892
+
23893
+ if (ellipsesProp.value && acc.pgFrom > (minProp.value + (boundaryNumbersProp.value ? 1 : 0))) {
23894
+ acc.ellipsesStart = true;
23895
+ acc.pgFrom++;
23896
+ }
23897
+
23898
+ if (boundaryNumbersProp.value) {
23899
+ acc.boundaryEnd = true;
23900
+ acc.pgTo--;
23901
+ }
23902
+
23903
+ if (ellipsesProp.value && acc.pgTo < (maxProp.value - (boundaryNumbersProp.value ? 1 : 0))) {
23904
+ acc.ellipsesEnd = true;
23905
+ acc.pgTo--;
23906
+ }
23907
+ }
23908
+
23909
+ return acc
23910
+ });
23911
+
23774
23912
  function set (value) {
23775
23913
  model.value = value;
23776
23914
  }
@@ -23779,20 +23917,40 @@
23779
23917
  model.value = model.value + offset;
23780
23918
  }
23781
23919
 
23782
- function updateModel () {
23783
- model.value = newPage.value;
23784
- newPage.value = null;
23785
- }
23920
+ const inputEvents = vue.computed(() => {
23921
+ function updateModel () {
23922
+ model.value = newPage.value;
23923
+ newPage.value = null;
23924
+ }
23925
+
23926
+ return {
23927
+ 'onUpdate:modelValue': val => { newPage.value = val; },
23928
+ onKeyup: e => { isKeyCode(e, 13) === true && updateModel(); },
23929
+ onBlur: updateModel
23930
+ }
23931
+ });
23786
23932
 
23787
- function getBtn (cfg, page) {
23788
- const data = { ...btnProps.value, ...cfg };
23933
+ function getBtn (cfg, page, active) {
23934
+ const data = {
23935
+ 'aria-label': page,
23936
+ 'aria-current': 'false',
23937
+ ...btnProps.value,
23938
+ ...cfg
23939
+ };
23940
+
23941
+ if (active === true) {
23942
+ Object.assign(data, {
23943
+ 'aria-current': 'true',
23944
+ ...activeBtnProps.value
23945
+ });
23946
+ }
23789
23947
 
23790
23948
  if (page !== void 0) {
23791
23949
  if (props.toFn !== void 0) {
23792
23950
  data.to = props.toFn(page);
23793
23951
  }
23794
23952
  else {
23795
- data.onClick = () => set(page);
23953
+ data.onClick = () => { set(page); };
23796
23954
  }
23797
23955
  }
23798
23956
 
@@ -23803,147 +23961,107 @@
23803
23961
  Object.assign(proxy, { set, setByOffset });
23804
23962
 
23805
23963
  return () => {
23806
- const
23807
- contentStart = [],
23808
- contentEnd = [],
23809
- contentMiddle = [];
23964
+ const contentStart = [];
23965
+ const contentEnd = [];
23966
+ let contentMiddle;
23967
+
23968
+ if (boundaryLinksProp.value === true) {
23969
+ contentStart.push(
23970
+ getBtn({
23971
+ key: 'bls',
23972
+ disable: props.disable || props.modelValue <= minProp.value,
23973
+ icon: icons.value[ 0 ]
23974
+ }, minProp.value)
23975
+ );
23810
23976
 
23811
- if (__boundaryLinks.value) {
23812
- contentStart.push(getBtn({
23813
- key: 'bls',
23814
- disable: props.disable || props.modelValue <= props.min,
23815
- icon: icons.value[ 0 ]
23816
- }, props.min));
23817
- contentEnd.unshift(getBtn({
23818
- key: 'ble',
23819
- disable: props.disable || props.modelValue >= props.max,
23820
- icon: icons.value[ 3 ]
23821
- }, props.max));
23822
- }
23823
-
23824
- if (__directionLinks.value) {
23825
- contentStart.push(getBtn({
23826
- key: 'bdp',
23827
- disable: props.disable || props.modelValue <= props.min,
23828
- icon: icons.value[ 1 ]
23829
- }, props.modelValue - 1));
23830
- contentEnd.unshift(getBtn({
23831
- key: 'bdn',
23832
- disable: props.disable || props.modelValue >= props.max,
23833
- icon: icons.value[ 2 ]
23834
- }, props.modelValue + 1));
23835
- }
23836
-
23837
- if (props.input === true) {
23838
- contentMiddle.push(vue.h(QInput, {
23839
- class: 'inline',
23840
- style: {
23841
- width: `${ inputPlaceholder.value.length / 1.5 }em`
23842
- },
23843
- type: 'number',
23844
- dense: true,
23845
- value: newPage.value,
23846
- disable: props.disable,
23847
- dark: isDark.value,
23848
- borderless: true,
23849
- inputClass: props.inputClass,
23850
- inputStyle: props.inputStyle,
23851
- placeholder: inputPlaceholder.value,
23852
- min: props.min,
23853
- max: props.max,
23854
- 'onUpdate:modelValue' (value) { newPage.value = value; },
23855
- onKeyup (e) { isKeyCode(e, 13) === true && updateModel(); },
23856
- onBlur: updateModel
23857
- }));
23977
+ contentEnd.unshift(
23978
+ getBtn({
23979
+ key: 'ble',
23980
+ disable: props.disable || props.modelValue >= maxProp.value,
23981
+ icon: icons.value[ 3 ]
23982
+ }, maxProp.value)
23983
+ );
23858
23984
  }
23859
- else { // is type select
23860
- let
23861
- maxPages = Math.max(
23862
- props.maxPages,
23863
- 1 + (__ellipses.value ? 2 : 0) + (__boundaryNumbers.value ? 2 : 0)
23864
- ),
23865
- pgFrom = props.min,
23866
- pgTo = props.max,
23867
- ellipsesStart = false,
23868
- ellipsesEnd = false,
23869
- boundaryStart = false,
23870
- boundaryEnd = false;
23871
-
23872
- if (props.maxPages && maxPages < (props.max - props.min + 1)) {
23873
- maxPages = 1 + Math.floor(maxPages / 2) * 2;
23874
- pgFrom = Math.max(props.min, Math.min(props.max - maxPages + 1, props.modelValue - Math.floor(maxPages / 2)));
23875
- pgTo = Math.min(props.max, pgFrom + maxPages - 1);
23876
- if (__boundaryNumbers.value) {
23877
- boundaryStart = true;
23878
- pgFrom += 1;
23879
- }
23880
- if (__ellipses.value && pgFrom > (props.min + (__boundaryNumbers.value ? 1 : 0))) {
23881
- ellipsesStart = true;
23882
- pgFrom += 1;
23883
- }
23884
- if (__boundaryNumbers.value) {
23885
- boundaryEnd = true;
23886
- pgTo -= 1;
23887
- }
23888
- if (__ellipses.value && pgTo < (props.max - (__boundaryNumbers.value ? 1 : 0))) {
23889
- ellipsesEnd = true;
23890
- pgTo -= 1;
23891
- }
23985
+
23986
+ if (directionLinksProp.value === true) {
23987
+ contentStart.push(
23988
+ getBtn({
23989
+ key: 'bdp',
23990
+ disable: props.disable || props.modelValue <= minProp.value,
23991
+ icon: icons.value[ 1 ]
23992
+ }, props.modelValue - 1)
23993
+ );
23994
+
23995
+ contentEnd.unshift(
23996
+ getBtn({
23997
+ key: 'bdn',
23998
+ disable: props.disable || props.modelValue >= maxProp.value,
23999
+ icon: icons.value[ 2 ]
24000
+ }, props.modelValue + 1)
24001
+ );
24002
+ }
24003
+
24004
+ if (props.input !== true) { // has buttons instead of inputbox
24005
+ contentMiddle = [];
24006
+ const { pgFrom, pgTo, marginalStyle: style } = btnConfig.value;
24007
+
24008
+ if (btnConfig.value.boundaryStart === true) {
24009
+ const active = minProp.value === props.modelValue;
24010
+ contentStart.push(
24011
+ getBtn({
24012
+ key: 'bns',
24013
+ style,
24014
+ disable: props.disable,
24015
+ label: minProp.value
24016
+ }, minProp.value, active)
24017
+ );
23892
24018
  }
23893
- const style = {
23894
- minWidth: `${ Math.max(2, String(props.max).length) }em`
23895
- };
23896
- if (boundaryStart) {
23897
- const active = props.min === props.modelValue;
23898
- contentStart.push(getBtn({
23899
- key: 'bns',
23900
- style,
23901
- disable: props.disable,
23902
- flat: !active,
23903
- label: props.min,
23904
- ...(active ? activeBtnProps.value : {})
23905
- }, props.min));
23906
- }
23907
- if (boundaryEnd) {
23908
- const active = props.max === props.modelValue;
23909
- contentEnd.unshift(getBtn({
23910
- key: 'bne',
23911
- style,
23912
- disable: props.disable,
23913
- flat: !active,
23914
- label: props.max,
23915
- ...(active ? activeBtnProps.value : {})
23916
- }, props.max));
23917
- }
23918
- if (ellipsesStart) {
23919
- contentStart.push(getBtn({
23920
- key: 'bes',
23921
- style,
23922
- disable: props.disable,
23923
- label: '…',
23924
- ripple: false
23925
- }, pgFrom - 1));
23926
- }
23927
- if (ellipsesEnd) {
23928
- contentEnd.unshift(getBtn({
23929
- key: 'bee',
23930
- style,
23931
- disable: props.disable,
23932
- label: '…',
23933
- ripple: false
23934
- }, pgTo + 1));
24019
+
24020
+ if (btnConfig.value.boundaryEnd === true) {
24021
+ const active = maxProp.value === props.modelValue;
24022
+ contentEnd.unshift(
24023
+ getBtn({
24024
+ key: 'bne',
24025
+ style,
24026
+ disable: props.disable,
24027
+ label: maxProp.value
24028
+ }, maxProp.value, active)
24029
+ );
23935
24030
  }
24031
+
24032
+ if (btnConfig.value.ellipsesStart === true) {
24033
+ contentStart.push(
24034
+ getBtn({
24035
+ key: 'bes',
24036
+ style,
24037
+ disable: props.disable,
24038
+ label: '…',
24039
+ ripple: false
24040
+ }, pgFrom - 1)
24041
+ );
24042
+ }
24043
+
24044
+ if (btnConfig.value.ellipsesEnd === true) {
24045
+ contentEnd.unshift(
24046
+ getBtn({
24047
+ key: 'bee',
24048
+ style,
24049
+ disable: props.disable,
24050
+ label: '…',
24051
+ ripple: false
24052
+ }, pgTo + 1)
24053
+ );
24054
+ }
24055
+
23936
24056
  for (let i = pgFrom; i <= pgTo; i++) {
23937
- const btn = {
23938
- key: `bpg${ i }`,
23939
- style,
23940
- disable: props.disable,
23941
- label: i
23942
- };
23943
- if (i === props.modelValue) {
23944
- Object.assign(btn, activeBtnProps.value);
23945
- }
23946
- contentMiddle.push(getBtn(btn, i));
24057
+ contentMiddle.push(
24058
+ getBtn({
24059
+ key: `bpg${ i }`,
24060
+ style,
24061
+ disable: props.disable,
24062
+ label: i
24063
+ }, i, i === props.modelValue)
24064
+ );
23947
24065
  }
23948
24066
  }
23949
24067
 
@@ -23951,15 +24069,35 @@
23951
24069
  class: classes.value,
23952
24070
  ...attrs.value
23953
24071
  }, [
23954
- contentStart,
23955
-
23956
24072
  vue.h('div', {
23957
- class: 'row justify-center'
24073
+ class: 'q-pagination__content row no-wrap items-center',
24074
+ style: gutterStyle.value
23958
24075
  }, [
23959
- contentMiddle
23960
- ]),
24076
+ ...contentStart,
24077
+
24078
+ props.input === true
24079
+ ? vue.h(QInput, {
24080
+ class: 'inline',
24081
+ style: { width: `${ inputPlaceholder.value.length / 1.5 }em` },
24082
+ type: 'number',
24083
+ dense: true,
24084
+ value: newPage.value,
24085
+ disable: props.disable,
24086
+ dark: isDark.value,
24087
+ borderless: true,
24088
+ inputClass: props.inputClass,
24089
+ inputStyle: props.inputStyle,
24090
+ placeholder: inputPlaceholder.value,
24091
+ min: minProp.value,
24092
+ max: maxProp.value,
24093
+ ...inputEvents.value
24094
+ })
24095
+ : vue.h('div', {
24096
+ class: 'q-pagination__middle row justify-center'
24097
+ }, contentMiddle),
23961
24098
 
23962
- contentEnd
24099
+ ...contentEnd
24100
+ ])
23963
24101
  ])
23964
24102
  }
23965
24103
  }
@@ -30878,9 +31016,11 @@
30878
31016
  setup (props, { slots, emit }) {
30879
31017
  const { proxy: { $q } } = vue.getCurrentInstance();
30880
31018
 
30881
- const $stepper = vue.inject(stepperKey, () => {
30882
- console.error('QStep needs to be child of QStepper');
30883
- });
31019
+ const $stepper = vue.inject(stepperKey, emptyRenderFn);
31020
+ if ($stepper === emptyRenderFn) {
31021
+ console.error('QStep needs to be a child of QStepper');
31022
+ return emptyRenderFn
31023
+ }
30884
31024
 
30885
31025
  const { getCacheWithFn } = useCache();
30886
31026
 
@@ -30938,7 +31078,7 @@
30938
31078
 
30939
31079
  return () => vue.h(
30940
31080
  'div',
30941
- { ref: rootRef, class: 'q-stepper__step', ...scrollEvent.value },
31081
+ { ref: rootRef, class: 'q-stepper__step', role: 'tabpanel', ...scrollEvent.value },
30942
31082
  $stepper.value.vertical === true
30943
31083
  ? [
30944
31084
  vue.h(StepHeader, {
@@ -34003,9 +34143,11 @@
34003
34143
  },
34004
34144
 
34005
34145
  setup (props, { slots }) {
34006
- const $timeline = vue.inject(timelineKey, () => {
34146
+ const $timeline = vue.inject(timelineKey, emptyRenderFn);
34147
+ if ($timeline === emptyRenderFn) {
34007
34148
  console.error('QTimelineEntry needs to be child of QTimeline');
34008
- });
34149
+ return emptyRenderFn
34150
+ }
34009
34151
 
34010
34152
  const classes = vue.computed(() =>
34011
34153
  `q-timeline__entry q-timeline__entry--${ props.side }`
@@ -34094,7 +34236,7 @@
34094
34236
  + (props.inset === true ? ' q-toolbar--inset' : '')
34095
34237
  );
34096
34238
 
34097
- return () => vue.h('div', { class: classes.value }, hSlot(slots.default))
34239
+ return () => vue.h('div', { class: classes.value, role: 'toolbar' }, hSlot(slots.default))
34098
34240
  }
34099
34241
  });
34100
34242
 
@@ -35582,9 +35724,13 @@
35582
35724
  name: 'QUploaderAddTrigger',
35583
35725
 
35584
35726
  setup () {
35585
- return vue.inject(uploaderKey, () => {
35727
+ const $trigger = vue.inject(uploaderKey, emptyRenderFn);
35728
+
35729
+ if ($trigger === emptyRenderFn) {
35586
35730
  console.error('QUploaderAddTrigger needs to be child of QUploader');
35587
- })
35731
+ }
35732
+
35733
+ return $trigger
35588
35734
  }
35589
35735
  });
35590
35736
 
@@ -37904,6 +38050,7 @@
37904
38050
  action.class
37905
38051
  ],
37906
38052
  tabindex: 0,
38053
+ role: 'listitem',
37907
38054
  onClick () { onOk(action); },
37908
38055
  onKeyup (e) { e.keyCode === 13 && onOk(action); }
37909
38056
  }, [
@@ -37979,9 +38126,12 @@
37979
38126
  child.push(
37980
38127
  props.grid === true
37981
38128
  ? vue.h('div', {
37982
- class: 'row items-stretch justify-start'
38129
+ class: 'row items-stretch justify-start',
38130
+ role: 'list'
37983
38131
  }, getGrid())
37984
- : vue.h('div', getList())
38132
+ : vue.h('div', {
38133
+ role: 'list'
38134
+ }, getList())
37985
38135
  );
37986
38136
 
37987
38137
  return child
@@ -40325,7 +40475,7 @@
40325
40475
  */
40326
40476
 
40327
40477
  var index_umd = {
40328
- version: '2.9.2',
40478
+ version: '2.10.0',
40329
40479
  install (app, opts) {
40330
40480
  installQuasar(app, {
40331
40481
  components,