quasar 2.21.4 → 2.23.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 (193) hide show
  1. package/README.md +1 -1
  2. package/dist/api/Mutation.json +1 -1
  3. package/dist/api/QLinearProgress.json +1 -1
  4. package/dist/api/QUploader.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/fontawesome-v7-pro.umd.prod.js +1 -1
  12. package/dist/icon-set/fontawesome-v7.umd.prod.js +1 -1
  13. package/dist/icon-set/ionicons-v4.umd.prod.js +1 -1
  14. package/dist/icon-set/line-awesome.umd.prod.js +1 -1
  15. package/dist/icon-set/material-icons-outlined.umd.prod.js +1 -1
  16. package/dist/icon-set/material-icons-round.umd.prod.js +1 -1
  17. package/dist/icon-set/material-icons-sharp.umd.prod.js +1 -1
  18. package/dist/icon-set/material-icons.umd.prod.js +1 -1
  19. package/dist/icon-set/material-symbols-outlined.umd.prod.js +1 -1
  20. package/dist/icon-set/material-symbols-rounded.umd.prod.js +1 -1
  21. package/dist/icon-set/material-symbols-sharp.umd.prod.js +1 -1
  22. package/dist/icon-set/mdi-v3.umd.prod.js +1 -1
  23. package/dist/icon-set/mdi-v4.umd.prod.js +1 -1
  24. package/dist/icon-set/mdi-v5.umd.prod.js +1 -1
  25. package/dist/icon-set/mdi-v6.umd.prod.js +1 -1
  26. package/dist/icon-set/mdi-v7.umd.prod.js +1 -1
  27. package/dist/icon-set/svg-bootstrap-icons.umd.prod.js +1 -1
  28. package/dist/icon-set/svg-eva-icons.umd.prod.js +1 -1
  29. package/dist/icon-set/svg-fontawesome-v5.umd.prod.js +1 -1
  30. package/dist/icon-set/svg-fontawesome-v6.umd.prod.js +1 -1
  31. package/dist/icon-set/svg-fontawesome-v7.umd.prod.js +1 -1
  32. package/dist/icon-set/svg-ionicons-v4.umd.prod.js +1 -1
  33. package/dist/icon-set/svg-ionicons-v5.umd.prod.js +1 -1
  34. package/dist/icon-set/svg-ionicons-v6.umd.prod.js +1 -1
  35. package/dist/icon-set/svg-ionicons-v7.umd.prod.js +1 -1
  36. package/dist/icon-set/svg-ionicons-v8.umd.prod.js +1 -1
  37. package/dist/icon-set/svg-line-awesome.umd.prod.js +1 -1
  38. package/dist/icon-set/svg-material-icons-outlined.umd.prod.js +1 -1
  39. package/dist/icon-set/svg-material-icons-round.umd.prod.js +1 -1
  40. package/dist/icon-set/svg-material-icons-sharp.umd.prod.js +1 -1
  41. package/dist/icon-set/svg-material-icons.umd.prod.js +1 -1
  42. package/dist/icon-set/svg-material-symbols-outlined.umd.prod.js +1 -1
  43. package/dist/icon-set/svg-material-symbols-rounded.umd.prod.js +1 -1
  44. package/dist/icon-set/svg-material-symbols-sharp.umd.prod.js +1 -1
  45. package/dist/icon-set/svg-mdi-v6.umd.prod.js +1 -1
  46. package/dist/icon-set/svg-mdi-v7.umd.prod.js +1 -1
  47. package/dist/icon-set/svg-themify.umd.prod.js +1 -1
  48. package/dist/icon-set/themify.umd.prod.js +1 -1
  49. package/dist/lang/ar-TN.umd.prod.js +1 -1
  50. package/dist/lang/ar.umd.prod.js +1 -1
  51. package/dist/lang/az-Latn.umd.prod.js +1 -1
  52. package/dist/lang/bg.umd.prod.js +1 -1
  53. package/dist/lang/bn.umd.prod.js +1 -1
  54. package/dist/lang/bs-BA.umd.prod.js +1 -1
  55. package/dist/lang/ca.umd.prod.js +1 -1
  56. package/dist/lang/cs.umd.prod.js +1 -1
  57. package/dist/lang/da.umd.prod.js +1 -1
  58. package/dist/lang/de-CH.umd.prod.js +1 -1
  59. package/dist/lang/de-DE.umd.prod.js +1 -1
  60. package/dist/lang/de.umd.prod.js +1 -1
  61. package/dist/lang/el.umd.prod.js +1 -1
  62. package/dist/lang/en-GB.umd.prod.js +1 -1
  63. package/dist/lang/en-US.umd.prod.js +1 -1
  64. package/dist/lang/eo.umd.prod.js +1 -1
  65. package/dist/lang/es.umd.prod.js +1 -1
  66. package/dist/lang/et.umd.prod.js +1 -1
  67. package/dist/lang/eu.umd.prod.js +1 -1
  68. package/dist/lang/fa-IR.umd.prod.js +1 -1
  69. package/dist/lang/fa.umd.prod.js +1 -1
  70. package/dist/lang/fi.umd.prod.js +1 -1
  71. package/dist/lang/fr.umd.prod.js +1 -1
  72. package/dist/lang/gn.umd.prod.js +1 -1
  73. package/dist/lang/he.umd.prod.js +1 -1
  74. package/dist/lang/hi.umd.prod.js +1 -1
  75. package/dist/lang/hr.umd.prod.js +1 -1
  76. package/dist/lang/hu.umd.prod.js +1 -1
  77. package/dist/lang/id.umd.prod.js +1 -1
  78. package/dist/lang/is.umd.prod.js +1 -1
  79. package/dist/lang/it.umd.prod.js +1 -1
  80. package/dist/lang/ja.umd.prod.js +1 -1
  81. package/dist/lang/kk.umd.prod.js +1 -1
  82. package/dist/lang/km.umd.prod.js +1 -1
  83. package/dist/lang/ko-KR.umd.prod.js +1 -1
  84. package/dist/lang/kur-CKB.umd.prod.js +1 -1
  85. package/dist/lang/lb.umd.prod.js +1 -1
  86. package/dist/lang/lt.umd.prod.js +1 -1
  87. package/dist/lang/lu.umd.prod.js +1 -1
  88. package/dist/lang/lv.umd.prod.js +1 -1
  89. package/dist/lang/mk.umd.prod.js +1 -1
  90. package/dist/lang/ml.umd.prod.js +1 -1
  91. package/dist/lang/mm.umd.prod.js +1 -1
  92. package/dist/lang/ms-MY.umd.prod.js +1 -1
  93. package/dist/lang/ms.umd.prod.js +1 -1
  94. package/dist/lang/my.umd.prod.js +1 -1
  95. package/dist/lang/nb-NO.umd.prod.js +1 -1
  96. package/dist/lang/nl.umd.prod.js +1 -1
  97. package/dist/lang/pl.umd.prod.js +1 -1
  98. package/dist/lang/pt-BR.umd.prod.js +1 -1
  99. package/dist/lang/pt.umd.prod.js +1 -1
  100. package/dist/lang/ro.umd.prod.js +1 -1
  101. package/dist/lang/ru.umd.prod.js +1 -1
  102. package/dist/lang/sk.umd.prod.js +1 -1
  103. package/dist/lang/sl.umd.prod.js +1 -1
  104. package/dist/lang/sm.umd.prod.js +1 -1
  105. package/dist/lang/sq.umd.prod.js +1 -1
  106. package/dist/lang/sr-CYR.umd.prod.js +1 -1
  107. package/dist/lang/sr.umd.prod.js +1 -1
  108. package/dist/lang/sv.umd.prod.js +1 -1
  109. package/dist/lang/ta.umd.prod.js +1 -1
  110. package/dist/lang/th.umd.prod.js +1 -1
  111. package/dist/lang/tl.umd.prod.js +1 -1
  112. package/dist/lang/tr.umd.prod.js +1 -1
  113. package/dist/lang/ug.umd.prod.js +1 -1
  114. package/dist/lang/uk.umd.prod.js +1 -1
  115. package/dist/lang/ur-PK.umd.prod.js +1 -1
  116. package/dist/lang/uz-Cyrl.umd.prod.js +1 -1
  117. package/dist/lang/uz-Latn.umd.prod.js +1 -1
  118. package/dist/lang/vi.umd.prod.js +1 -1
  119. package/dist/lang/zh-CN.umd.prod.js +1 -1
  120. package/dist/lang/zh-TW.umd.prod.js +1 -1
  121. package/dist/quasar.client.js +654 -207
  122. package/dist/quasar.css +20 -11
  123. package/dist/quasar.prod.css +1 -1
  124. package/dist/quasar.rtl.css +25 -20
  125. package/dist/quasar.rtl.prod.css +1 -1
  126. package/dist/quasar.sass +21 -12
  127. package/dist/quasar.server.prod.cjs +35 -35
  128. package/dist/quasar.server.prod.js +25 -25
  129. package/dist/quasar.umd.js +654 -206
  130. package/dist/quasar.umd.prod.js +19 -19
  131. package/dist/transforms/import-map.json +1 -1
  132. package/dist/types/composables.d.ts +15 -5
  133. package/dist/types/index.d.ts +5 -5
  134. package/dist/web-types/web-types.json +1 -1
  135. package/package.json +6 -6
  136. package/src/components/btn/QBtn.js +1 -1
  137. package/src/components/carousel/QCarousel.js +2 -0
  138. package/src/components/chip/QChip.js +20 -4
  139. package/src/components/date/QDate.js +9 -2
  140. package/src/components/dialog/QDialog.js +9 -2
  141. package/src/components/editor/QEditor.js +18 -3
  142. package/src/components/expansion-item/QExpansionItem.js +6 -1
  143. package/src/components/fab/QFab.sass +11 -9
  144. package/src/components/input/QInput.js +42 -1
  145. package/src/components/input/QInput.json +7 -0
  146. package/src/components/input/use-mask.js +12 -4
  147. package/src/components/item/QItem.js +10 -1
  148. package/src/components/linear-progress/QLinearProgress.js +4 -11
  149. package/src/components/linear-progress/QLinearProgress.json +1 -1
  150. package/src/components/linear-progress/QLinearProgress.sass +7 -2
  151. package/src/components/menu/QMenu.js +9 -2
  152. package/src/components/range/QRange.js +2 -1
  153. package/src/components/rating/QRating.js +27 -8
  154. package/src/components/rating/QRating.sass +4 -0
  155. package/src/components/resize-observer/QResizeObserver.js +14 -3
  156. package/src/components/scroll-area/QScrollArea.js +69 -17
  157. package/src/components/slide-item/QSlideItem.js +3 -2
  158. package/src/components/slider/use-slider.js +7 -3
  159. package/src/components/stepper/StepHeader.js +11 -2
  160. package/src/components/table/QTable.js +11 -9
  161. package/src/components/table/QTh.js +20 -1
  162. package/src/components/table/table-column-selection.js +9 -1
  163. package/src/components/table/table-pagination.js +5 -2
  164. package/src/components/table/table-row-selection.js +10 -10
  165. package/src/components/tabs/QTabs.js +5 -6
  166. package/src/components/time/QTime.js +35 -10
  167. package/src/components/tooltip/QTooltip.js +112 -6
  168. package/src/components/tree/QTree.js +124 -4
  169. package/src/components/uploader/uploader-core.js +19 -4
  170. package/src/components/uploader/xhr-uploader-plugin.js +93 -43
  171. package/src/components/uploader/xhr-uploader-plugin.json +4 -4
  172. package/src/composables/private.use-field/use-field.js +2 -0
  173. package/src/composables/private.use-file/use-file.js +21 -12
  174. package/src/composables/private.use-fullscreen/use-fullscreen.js +71 -11
  175. package/src/composables/private.use-fullscreen/use-fullscreen.test.js +158 -0
  176. package/src/composables/private.use-model-toggle/use-model-toggle.js +2 -0
  177. package/src/composables/private.use-panel/use-panel.js +6 -2
  178. package/src/composables/use-animation-frame/use-animation-frame.js +47 -0
  179. package/src/composables/use-animation-frame/use-animation-frame.test.js +122 -0
  180. package/src/composables/use-interval/use-interval.js +8 -0
  181. package/src/composables/use-render-cache/use-render-cache.js +15 -10
  182. package/src/composables/use-timeout/use-timeout.js +8 -0
  183. package/src/composables.js +1 -1
  184. package/src/directives/intersection/Intersection.js +2 -2
  185. package/src/directives/mutation/Mutation.json +1 -1
  186. package/src/directives/touch-repeat/TouchRepeat.js +3 -1
  187. package/src/plugins/cookies/Cookies.js +29 -13
  188. package/src/plugins/meta/Meta.js +57 -9
  189. package/src/utils/extend/extend.js +4 -0
  190. package/src/utils/extend/extend.test.js +29 -0
  191. package/src/utils/private.click-outside/click-outside.js +27 -12
  192. package/src/utils/private.click-outside/click-outside.test.js +132 -0
  193. package/src/utils/scroll/prevent-scroll.js +4 -4
@@ -0,0 +1,132 @@
1
+ import { afterEach, describe, expect, test, vi } from 'vitest'
2
+
3
+ import { addClickOutside, removeClickOutside } from './click-outside.js'
4
+ import { portalProxyList } from '../private.portal/portal.js'
5
+
6
+ // Elements and clickOutside states created during a test, cleaned up after.
7
+ const createdEls = []
8
+ const registeredStates = []
9
+
10
+ function createEl() {
11
+ const el = document.createElement('div')
12
+ document.body.append(el)
13
+ createdEls.push(el)
14
+ return el
15
+ }
16
+
17
+ // Register a fake portal (QMenu / QDialog / QTooltip) in the shared
18
+ // portalProxyList, mimicking what usePortal.showPortal() does.
19
+ function pushPortal(name, { seamless = false } = {}) {
20
+ const contentEl = createEl()
21
+ portalProxyList.push({
22
+ contentEl,
23
+ $: { type: { name }, props: { seamless } }
24
+ })
25
+ return contentEl
26
+ }
27
+
28
+ // Register a closable popup (QMenu-like) both as a portal and as a
29
+ // clickOutside listener, returning its content element and the spy.
30
+ function pushMenu() {
31
+ const contentEl = pushPortal('QMenu')
32
+ const onClickOutside = vi.fn()
33
+ const state = {
34
+ anchorEl: { value: null },
35
+ innerRef: { value: contentEl },
36
+ onClickOutside
37
+ }
38
+ addClickOutside(state)
39
+ registeredStates.push(state)
40
+ return { contentEl, onClickOutside }
41
+ }
42
+
43
+ function mousedownOn(el) {
44
+ el.dispatchEvent(new MouseEvent('mousedown', { bubbles: true }))
45
+ }
46
+
47
+ afterEach(() => {
48
+ registeredStates.forEach(removeClickOutside)
49
+ registeredStates.length = 0
50
+ portalProxyList.length = 0
51
+ createdEls.forEach(el => el.remove())
52
+ createdEls.length = 0
53
+ vi.restoreAllMocks()
54
+ })
55
+
56
+ describe('[clickOutside API]', () => {
57
+ describe('[Functions]', () => {
58
+ describe('[(function)addClickOutside]', () => {
59
+ test('closes nested menus that have no dialog between them', () => {
60
+ // stack (open order): outer QMenu -> inner QMenu
61
+ const outer = pushMenu()
62
+ const inner = pushMenu()
63
+
64
+ // click somewhere outside both menus
65
+ mousedownOn(createEl())
66
+
67
+ expect(inner.onClickOutside).toHaveBeenCalledTimes(1)
68
+ expect(outer.onClickOutside).toHaveBeenCalledTimes(1)
69
+ })
70
+
71
+ test('does not close a menu shielded by a modal dialog (issue #18091)', () => {
72
+ // stack (open order): outer QMenu -> modal QDialog -> inner QMenu
73
+ const outer = pushMenu()
74
+ const dialogEl = pushPortal('QDialog', { seamless: false })
75
+ const inner = pushMenu()
76
+
77
+ // click inside the dialog, but outside the inner menu popup
78
+ mousedownOn(dialogEl)
79
+
80
+ // only the inner Select popup should close
81
+ expect(inner.onClickOutside).toHaveBeenCalledTimes(1)
82
+ // the outer Select popup stays open (shielded by the dialog backdrop)
83
+ expect(outer.onClickOutside).not.toHaveBeenCalled()
84
+ })
85
+
86
+ test('a seamless dialog is not a boundary (has no backdrop)', () => {
87
+ // stack (open order): outer QMenu -> seamless QDialog -> inner QMenu
88
+ const outer = pushMenu()
89
+ const dialogEl = pushPortal('QDialog', { seamless: true })
90
+ const inner = pushMenu()
91
+
92
+ // click inside the seamless dialog, outside the inner menu popup
93
+ mousedownOn(dialogEl)
94
+
95
+ // without a backdrop, both menus close as before
96
+ expect(inner.onClickOutside).toHaveBeenCalledTimes(1)
97
+ expect(outer.onClickOutside).toHaveBeenCalledTimes(1)
98
+ })
99
+
100
+ test('a modal dialog on top closes nothing beneath it', () => {
101
+ // stack (open order): outer QMenu -> modal QDialog (top-most)
102
+ const outer = pushMenu()
103
+ const dialogEl = pushPortal('QDialog', { seamless: false })
104
+
105
+ mousedownOn(dialogEl)
106
+
107
+ expect(outer.onClickOutside).not.toHaveBeenCalled()
108
+ })
109
+
110
+ test('a QTooltip above a modal dialog does not unshield an earlier menu', () => {
111
+ // stack (open order): outer QMenu -> modal QDialog -> QTooltip
112
+ // the QTooltip is skipped while scanning for the dialog boundary; that
113
+ // skip must not let the click reach the menu opened before the dialog
114
+ const outer = pushMenu()
115
+ const dialogEl = pushPortal('QDialog', { seamless: false })
116
+ pushPortal('QTooltip')
117
+
118
+ // click inside the dialog, outside every popup
119
+ mousedownOn(dialogEl)
120
+
121
+ expect(outer.onClickOutside).not.toHaveBeenCalled()
122
+ })
123
+ })
124
+
125
+ describe('[(function)removeClickOutside]', () => {
126
+ test('has correct return value', () => {
127
+ const result = removeClickOutside({})
128
+ expect(result).toBeUndefined()
129
+ })
130
+ })
131
+ })
132
+ })
@@ -12,7 +12,7 @@ let registered = 0,
12
12
  vpPendingUpdate = false,
13
13
  bodyLeft,
14
14
  bodyTop,
15
- href,
15
+ routePath,
16
16
  closeTimer = null
17
17
 
18
18
  function onAppleScroll(e) {
@@ -59,7 +59,7 @@ function apply(action) {
59
59
  bodyLeft = body.style.left
60
60
  bodyTop = body.style.top
61
61
 
62
- href = window.location.href
62
+ routePath = window.location.pathname
63
63
 
64
64
  body.style.left = `-${scrollPositionX}px`
65
65
  body.style.top = `-${scrollPositionY}px`
@@ -137,8 +137,8 @@ function apply(action) {
137
137
  body.style.left = bodyLeft
138
138
  body.style.top = bodyTop
139
139
 
140
- // scroll back only if route has not changed
141
- if (window.location.href === href) {
140
+ // scroll back only if route path has not changed
141
+ if (window.location.pathname === routePath) {
142
142
  window.scrollTo(scrollPositionX, scrollPositionY)
143
143
  }
144
144