quasar 2.3.4 → 2.4.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.
- package/dist/api/Loading.json +2 -6
- package/dist/api/QBreadcrumbsEl.json +31 -10
- package/dist/api/QBtn.json +30 -14
- package/dist/api/QBtnDropdown.json +30 -14
- package/dist/api/QBtnToggle.json +3 -0
- package/dist/api/QChatMessage.json +4 -12
- package/dist/api/QExpansionItem.json +31 -10
- package/dist/api/QFab.json +30 -0
- package/dist/api/QFabAction.json +8 -0
- package/dist/api/QField.json +1 -0
- package/dist/api/QFile.json +1 -0
- package/dist/api/QInput.json +1 -0
- package/dist/api/QItem.json +31 -10
- package/dist/api/QOptionGroup.json +74 -4
- package/dist/api/QRange.json +592 -107
- package/dist/api/QRouteTab.json +31 -11
- package/dist/api/QSelect.json +3 -6
- package/dist/api/QSlider.json +504 -39
- package/dist/api/QUploader.json +16 -2
- package/dist/icon-set/bootstrap-icons.umd.prod.js +1 -1
- package/dist/icon-set/eva-icons.umd.prod.js +1 -1
- package/dist/icon-set/fontawesome-v5-pro.umd.prod.js +1 -1
- package/dist/icon-set/fontawesome-v5.umd.prod.js +1 -1
- package/dist/icon-set/ionicons-v4.umd.prod.js +1 -1
- package/dist/icon-set/line-awesome.umd.prod.js +1 -1
- package/dist/icon-set/material-icons-outlined.umd.prod.js +1 -1
- package/dist/icon-set/material-icons-round.umd.prod.js +1 -1
- package/dist/icon-set/material-icons-sharp.umd.prod.js +1 -1
- package/dist/icon-set/material-icons.umd.prod.js +1 -1
- package/dist/icon-set/mdi-v3.umd.prod.js +1 -1
- package/dist/icon-set/mdi-v4.umd.prod.js +1 -1
- package/dist/icon-set/mdi-v5.umd.prod.js +1 -1
- package/dist/icon-set/mdi-v6.umd.prod.js +1 -1
- package/dist/icon-set/svg-bootstrap-icons.umd.prod.js +1 -1
- package/dist/icon-set/svg-eva-icons.umd.prod.js +1 -1
- package/dist/icon-set/svg-fontawesome-v5.umd.prod.js +1 -1
- package/dist/icon-set/svg-ionicons-v4.umd.prod.js +1 -1
- package/dist/icon-set/svg-ionicons-v5.umd.prod.js +1 -1
- package/dist/icon-set/svg-ionicons-v6.umd.prod.js +1 -1
- package/dist/icon-set/svg-line-awesome.umd.prod.js +1 -1
- package/dist/icon-set/svg-material-icons-outlined.umd.prod.js +1 -1
- package/dist/icon-set/svg-material-icons-round.umd.prod.js +1 -1
- package/dist/icon-set/svg-material-icons-sharp.umd.prod.js +1 -1
- package/dist/icon-set/svg-material-icons.umd.prod.js +1 -1
- package/dist/icon-set/svg-mdi-v4.umd.prod.js +1 -1
- package/dist/icon-set/svg-mdi-v5.umd.prod.js +1 -1
- package/dist/icon-set/svg-mdi-v6.umd.prod.js +1 -1
- package/dist/icon-set/svg-themify.umd.prod.js +1 -1
- package/dist/icon-set/themify.umd.prod.js +1 -1
- package/dist/lang/ar.umd.prod.js +1 -1
- package/dist/lang/az-Latn.umd.prod.js +1 -1
- package/dist/lang/bg.umd.prod.js +1 -1
- package/dist/lang/bn.umd.prod.js +1 -1
- package/dist/lang/ca.umd.prod.js +1 -1
- package/dist/lang/cs.umd.prod.js +1 -1
- package/dist/lang/da.umd.prod.js +1 -1
- package/dist/lang/de.umd.prod.js +1 -1
- package/dist/lang/el.umd.prod.js +1 -1
- package/dist/lang/en-GB.umd.prod.js +1 -1
- package/dist/lang/en-US.umd.prod.js +1 -1
- package/dist/lang/eo.umd.prod.js +1 -1
- package/dist/lang/es.umd.prod.js +1 -1
- package/dist/lang/et.umd.prod.js +1 -1
- package/dist/lang/fa-IR.umd.prod.js +1 -1
- package/dist/lang/fa.umd.prod.js +1 -1
- package/dist/lang/fi.umd.prod.js +1 -1
- package/dist/lang/fr.umd.prod.js +1 -1
- package/dist/lang/gn.umd.prod.js +1 -1
- package/dist/lang/he.umd.prod.js +1 -1
- package/dist/lang/hr.umd.prod.js +1 -1
- package/dist/lang/hu.umd.prod.js +1 -1
- package/dist/lang/id.umd.prod.js +1 -1
- package/dist/lang/is.umd.prod.js +1 -1
- package/dist/lang/it.umd.prod.js +1 -1
- package/dist/lang/ja.umd.prod.js +1 -1
- package/dist/lang/km.umd.prod.js +1 -1
- package/dist/lang/ko-KR.umd.prod.js +1 -1
- package/dist/lang/kur-CKB.umd.prod.js +1 -1
- package/dist/lang/lt.umd.prod.js +1 -1
- package/dist/lang/lu.umd.prod.js +1 -1
- package/dist/lang/lv.umd.prod.js +1 -1
- package/dist/lang/ml.umd.prod.js +1 -1
- package/dist/lang/ms.umd.prod.js +1 -1
- package/dist/lang/nb-NO.umd.prod.js +1 -1
- package/dist/lang/nl.umd.prod.js +1 -1
- package/dist/lang/pl.umd.prod.js +1 -1
- package/dist/lang/pt-BR.umd.prod.js +1 -1
- package/dist/lang/pt.umd.prod.js +1 -1
- package/dist/lang/ro.umd.prod.js +1 -1
- package/dist/lang/ru.umd.prod.js +1 -1
- package/dist/lang/sk.umd.prod.js +1 -1
- package/dist/lang/sl.umd.prod.js +1 -1
- package/dist/lang/sr-CYR.umd.prod.js +1 -1
- package/dist/lang/sr.umd.prod.js +1 -1
- package/dist/lang/sv.umd.prod.js +1 -1
- package/dist/lang/ta.umd.prod.js +1 -1
- package/dist/lang/th.umd.prod.js +1 -1
- package/dist/lang/tr.umd.prod.js +1 -1
- package/dist/lang/ug.umd.prod.js +1 -1
- package/dist/lang/uk.umd.prod.js +1 -1
- package/dist/lang/vi.umd.prod.js +1 -1
- package/dist/lang/zh-CN.umd.prod.js +1 -1
- package/dist/lang/zh-TW.umd.prod.js +1 -1
- package/dist/quasar.cjs.prod.js +2 -2
- package/dist/quasar.css +264 -183
- package/dist/quasar.esm.prod.js +2 -2
- package/dist/quasar.prod.css +1 -1
- package/dist/quasar.rtl.css +331 -262
- package/dist/quasar.rtl.prod.css +1 -1
- package/dist/quasar.sass +235 -178
- package/dist/quasar.umd.js +16537 -16226
- package/dist/quasar.umd.prod.js +2 -2
- package/dist/ssr-directives/Morph.js +1 -1
- package/dist/transforms/loader-asset-urls.json +20 -0
- package/dist/types/api/slider.d.ts +46 -0
- package/dist/types/api/validation.d.ts +4 -0
- package/dist/types/api.d.ts +2 -0
- package/dist/types/composables.d.ts +3 -3
- package/dist/types/index.d.ts +594 -120
- package/dist/vetur/quasar-attributes.json +250 -82
- package/dist/vetur/quasar-tags.json +59 -17
- package/dist/web-types/web-types.json +578 -149
- package/package.json +1 -1
- package/src/api.extends.json +0 -1
- package/src/components/breadcrumbs/QBreadcrumbs.js +7 -2
- package/src/components/breadcrumbs/QBreadcrumbs.sass +0 -3
- package/src/components/breadcrumbs/QBreadcrumbsEl.js +14 -8
- package/src/components/btn/QBtn.js +5 -5
- package/src/components/btn/use-btn.js +21 -21
- package/src/components/btn/use-btn.json +22 -13
- package/src/components/btn-toggle/QBtnToggle.json +3 -0
- package/src/components/checkbox/use-checkbox.js +1 -1
- package/src/components/color/QColor.js +32 -26
- package/src/components/color/QColor.sass +10 -23
- package/src/components/date/QDate.sass +2 -0
- package/src/components/drawer/QDrawer.js +18 -15
- package/src/components/editor/QEditor.js +1 -1
- package/src/components/editor/QEditor.sass +10 -1
- package/src/components/expansion-item/QExpansionItem.js +4 -1
- package/src/components/fab/QFab.js +18 -12
- package/src/components/fab/QFab.json +33 -0
- package/src/components/fab/QFab.sass +1 -1
- package/src/components/fab/QFabAction.js +14 -7
- package/src/components/fab/QFabAction.json +10 -0
- package/src/components/file/QFile.js +12 -5
- package/src/components/file/QFile.sass +4 -2
- package/src/components/footer/QFooter.js +1 -1
- package/src/components/header/QHeader.js +1 -1
- package/src/components/icon/QIcon.js +1 -1
- package/src/components/infinite-scroll/QInfiniteScroll.js +4 -5
- package/src/components/item/QItem.js +2 -3
- package/src/components/option-group/QOptionGroup.js +3 -0
- package/src/components/option-group/QOptionGroup.json +48 -2
- package/src/components/parallax/QParallax.js +4 -2
- package/src/components/popup-edit/QPopupEdit.js +2 -5
- package/src/components/radio/QRadio.js +2 -7
- package/src/components/range/QRange.js +103 -222
- package/src/components/range/QRange.json +11 -121
- package/src/components/scroll-area/QScrollArea.js +3 -1
- package/src/components/slider/QSlider.js +46 -132
- package/src/components/slider/QSlider.json +1 -121
- package/src/components/slider/QSlider.sass +198 -132
- package/src/components/slider/use-slider.js +453 -109
- package/src/components/slider/use-slider.json +546 -0
- package/src/components/stepper/QStepper.js +3 -3
- package/src/components/stepper/QStepper.sass +24 -26
- package/src/components/table/QTable.js +26 -46
- package/src/components/tabs/QRouteTab.js +1 -2
- package/src/components/tabs/QRouteTab.json +0 -7
- package/src/components/tabs/QTabs.js +71 -20
- package/src/components/tabs/use-tab.js +26 -13
- package/src/components/tree/QTree.js +14 -12
- package/src/components/uploader/QUploader.json +14 -2
- package/src/components/uploader/uploader-core.js +16 -9
- package/src/components/virtual-scroll/QVirtualScroll.sass +1 -0
- package/src/components/virtual-scroll/use-virtual-scroll.js +30 -17
- package/src/composables/private/use-field.js +5 -5
- package/src/composables/private/use-file.js +20 -5
- package/src/composables/private/use-form.js +2 -3
- package/src/composables/private/use-fullscreen.js +15 -4
- package/src/composables/private/use-router-link.js +44 -23
- package/src/composables/private/use-router-link.json +26 -10
- package/src/composables/private/use-split-attrs.js +4 -4
- package/src/composables/private/use-validate.js +21 -15
- package/src/composables/private/use-validate.json +1 -0
- package/src/css/core/helpers.sass +3 -0
- package/src/css/core/positioning.sass +5 -0
- package/src/directives/ScrollFire.js +1 -0
- package/src/icon-set.js +2 -4
- package/src/plugins/AppFullscreen.js +70 -53
- package/src/plugins/AppVisibility.js +2 -3
- package/src/plugins/BottomSheet.js +3 -5
- package/src/plugins/Dialog.js +3 -5
- package/src/plugins/LoadingBar.js +17 -18
- package/src/plugins/Notify.js +296 -295
- package/src/plugins/Platform.js +14 -14
- package/src/utils/date.js +4 -4
- package/src/utils/dom.js +2 -2
- package/src/utils/open-url.js +2 -2
- package/src/utils/patterns.js +1 -0
- package/src/utils/private/define-reactive-plugin.js +10 -8
- package/src/utils/private/global-dialog.js +6 -8
- package/src/utils/private/inject-obj-prop.js +13 -0
- package/src/utils/private/is.js +2 -2
|
@@ -15,8 +15,8 @@ const scrollToEdges = [
|
|
|
15
15
|
'end-force'
|
|
16
16
|
]
|
|
17
17
|
|
|
18
|
-
const slice = Array.prototype.slice
|
|
19
18
|
let id = 1
|
|
19
|
+
const filterProto = Array.prototype.filter
|
|
20
20
|
|
|
21
21
|
const setOverflowAnchor = __QUASAR_SSR__ || window.getComputedStyle(document.body).overflowAnchor === void 0
|
|
22
22
|
? noop
|
|
@@ -66,7 +66,7 @@ function getScrollDetails (
|
|
|
66
66
|
if (horizontal === true) {
|
|
67
67
|
if (parent === window) {
|
|
68
68
|
details.scrollStart = window.pageXOffset || window.scrollX || document.body.scrollLeft || 0
|
|
69
|
-
details.scrollViewSize +=
|
|
69
|
+
details.scrollViewSize += document.documentElement.clientWidth
|
|
70
70
|
}
|
|
71
71
|
else {
|
|
72
72
|
details.scrollStart = parentCalc.scrollLeft
|
|
@@ -81,7 +81,7 @@ function getScrollDetails (
|
|
|
81
81
|
else {
|
|
82
82
|
if (parent === window) {
|
|
83
83
|
details.scrollStart = window.pageYOffset || window.scrollY || document.body.scrollTop || 0
|
|
84
|
-
details.scrollViewSize +=
|
|
84
|
+
details.scrollViewSize += document.documentElement.clientHeight
|
|
85
85
|
}
|
|
86
86
|
else {
|
|
87
87
|
details.scrollStart = parentCalc.scrollTop
|
|
@@ -130,10 +130,16 @@ function getScrollDetails (
|
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
function setScroll (parent, scroll, horizontal, rtl) {
|
|
133
|
+
if (scroll === 'end') {
|
|
134
|
+
scroll = (parent === window ? document.body : parent)[
|
|
135
|
+
horizontal === true ? 'scrollWidth' : 'scrollHeight'
|
|
136
|
+
]
|
|
137
|
+
}
|
|
138
|
+
|
|
133
139
|
if (parent === window) {
|
|
134
140
|
if (horizontal === true) {
|
|
135
141
|
if (rtl === true) {
|
|
136
|
-
scroll = (rtlHasScrollBug === true ? document.body.scrollWidth -
|
|
142
|
+
scroll = (rtlHasScrollBug === true ? document.body.scrollWidth - document.documentElement.clientWidth : 0) - scroll
|
|
137
143
|
}
|
|
138
144
|
window.scrollTo(scroll, window.pageYOffset || window.scrollY || document.body.scrollTop || 0)
|
|
139
145
|
}
|
|
@@ -398,20 +404,17 @@ export function useVirtualScroll ({
|
|
|
398
404
|
}
|
|
399
405
|
|
|
400
406
|
const { activeElement } = document
|
|
407
|
+
const contentEl = contentRef.value
|
|
401
408
|
if (
|
|
402
409
|
rangeChanged === true
|
|
403
|
-
&&
|
|
404
|
-
&&
|
|
405
|
-
&&
|
|
410
|
+
&& contentEl !== null
|
|
411
|
+
&& contentEl !== activeElement
|
|
412
|
+
&& contentEl.contains(activeElement) === true
|
|
406
413
|
) {
|
|
407
|
-
|
|
408
|
-
contentRef.value.focus()
|
|
409
|
-
}
|
|
414
|
+
contentEl.addEventListener('focusout', onBlurRefocusFn)
|
|
410
415
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
requestAnimationFrame(() => {
|
|
414
|
-
activeElement.removeEventListener('blur', onBlurFn, true)
|
|
416
|
+
setTimeout(() => {
|
|
417
|
+
contentEl !== void 0 && contentEl.removeEventListener('focusout', onBlurRefocusFn)
|
|
415
418
|
})
|
|
416
419
|
}
|
|
417
420
|
|
|
@@ -489,8 +492,10 @@ export function useVirtualScroll ({
|
|
|
489
492
|
|
|
490
493
|
if (contentEl) {
|
|
491
494
|
const
|
|
492
|
-
children =
|
|
493
|
-
.
|
|
495
|
+
children = filterProto.call(
|
|
496
|
+
contentEl.children,
|
|
497
|
+
el => el.classList && el.classList.contains('q-virtual-scroll--skip') === false
|
|
498
|
+
),
|
|
494
499
|
childrenLength = children.length,
|
|
495
500
|
sizeFn = props.virtualScrollHorizontal === true
|
|
496
501
|
? el => el.getBoundingClientRect().width
|
|
@@ -521,6 +526,10 @@ export function useVirtualScroll ({
|
|
|
521
526
|
}
|
|
522
527
|
}
|
|
523
528
|
|
|
529
|
+
function onBlurRefocusFn () {
|
|
530
|
+
contentRef.value !== void 0 && contentRef.value.focus()
|
|
531
|
+
}
|
|
532
|
+
|
|
524
533
|
function localResetVirtualScroll (toIndex, fullReset) {
|
|
525
534
|
const defaultSize = 1 * virtualScrollItemSizeComputed.value
|
|
526
535
|
|
|
@@ -673,7 +682,10 @@ export function useVirtualScroll ({
|
|
|
673
682
|
}
|
|
674
683
|
|
|
675
684
|
setVirtualScrollSize()
|
|
676
|
-
const onVirtualScrollEvt = debounce(
|
|
685
|
+
const onVirtualScrollEvt = debounce(
|
|
686
|
+
localOnVirtualScrollEvt,
|
|
687
|
+
$q.platform.is.ios === true ? 120 : 35
|
|
688
|
+
)
|
|
677
689
|
|
|
678
690
|
onBeforeMount(() => {
|
|
679
691
|
setVirtualScrollSize()
|
|
@@ -698,6 +710,7 @@ export function useVirtualScroll ({
|
|
|
698
710
|
setOverflowAnchor !== noop && onBeforeUnmount(() => {
|
|
699
711
|
const styleSheet = document.getElementById(vsId + '_ss')
|
|
700
712
|
styleSheet !== null && styleSheet.remove()
|
|
713
|
+
onVirtualScrollEvt.cancel()
|
|
701
714
|
})
|
|
702
715
|
|
|
703
716
|
// expose public methods
|
|
@@ -168,7 +168,7 @@ export default function (state) {
|
|
|
168
168
|
isDirtyModel,
|
|
169
169
|
hasRules,
|
|
170
170
|
hasError,
|
|
171
|
-
|
|
171
|
+
errorMessage,
|
|
172
172
|
resetValidation
|
|
173
173
|
} = useValidate(state.focused, state.innerLoading)
|
|
174
174
|
|
|
@@ -348,7 +348,7 @@ export default function (state) {
|
|
|
348
348
|
nextTick(() => {
|
|
349
349
|
resetValidation()
|
|
350
350
|
|
|
351
|
-
if (
|
|
351
|
+
if ($q.platform.is.mobile !== true) {
|
|
352
352
|
isDirtyModel.value = false
|
|
353
353
|
}
|
|
354
354
|
})
|
|
@@ -473,9 +473,9 @@ export default function (state) {
|
|
|
473
473
|
let msg, key
|
|
474
474
|
|
|
475
475
|
if (hasError.value === true) {
|
|
476
|
-
if (
|
|
477
|
-
msg = [ h('div', { role: 'alert' },
|
|
478
|
-
key = `q--slot-error-${
|
|
476
|
+
if (errorMessage.value !== null) {
|
|
477
|
+
msg = [ h('div', { role: 'alert' }, errorMessage.value) ]
|
|
478
|
+
key = `q--slot-error-${ errorMessage.value }`
|
|
479
479
|
}
|
|
480
480
|
else {
|
|
481
481
|
msg = hSlot(slots.error)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { h, computed, getCurrentInstance } from 'vue'
|
|
2
2
|
|
|
3
|
-
import { stopAndPrevent } from '../../utils/event.js'
|
|
3
|
+
import { stop, stopAndPrevent } from '../../utils/event.js'
|
|
4
4
|
|
|
5
5
|
function filterFiles (files, rejectedFiles, failedPropValidation, filterFn) {
|
|
6
6
|
const acceptedFiles = []
|
|
@@ -62,8 +62,18 @@ export default function ({
|
|
|
62
62
|
|
|
63
63
|
function pickFiles (e) {
|
|
64
64
|
if (editable.value) {
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
if (e !== Object(e)) {
|
|
66
|
+
e = { target: null }
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (e.target !== null && e.target.matches('input[type="file"]') === true) {
|
|
70
|
+
// stop propagation if it's not a real pointer event
|
|
71
|
+
e.clientX === 0 && e.clientY === 0 && stop(e)
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
const input = getFileInput()
|
|
75
|
+
input && input !== e.target && input.click(e)
|
|
76
|
+
}
|
|
67
77
|
}
|
|
68
78
|
}
|
|
69
79
|
|
|
@@ -112,10 +122,15 @@ export default function ({
|
|
|
112
122
|
files = [ files[ 0 ] ]
|
|
113
123
|
}
|
|
114
124
|
|
|
125
|
+
// Compute key to use for each file
|
|
126
|
+
files.forEach(file => {
|
|
127
|
+
file.__key = file.webkitRelativePath + file.lastModified + file.name + file.size
|
|
128
|
+
})
|
|
129
|
+
|
|
115
130
|
// Avoid duplicate files
|
|
116
|
-
const filenameMap = currentFileList.map(entry => entry.
|
|
131
|
+
const filenameMap = currentFileList.map(entry => entry.__key)
|
|
117
132
|
files = filterFiles(files, rejectedFiles, 'duplicate', file => {
|
|
118
|
-
return filenameMap.includes(file.
|
|
133
|
+
return filenameMap.includes(file.__key) === false
|
|
119
134
|
})
|
|
120
135
|
|
|
121
136
|
if (files.length === 0) { return done() }
|
|
@@ -12,13 +12,12 @@ export function useFormAttrs (props) {
|
|
|
12
12
|
}))
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
export function useFormInject (formAttrs = {}
|
|
15
|
+
export function useFormInject (formAttrs = {}) {
|
|
16
16
|
return (child, action, className) => {
|
|
17
17
|
child[ action ](
|
|
18
18
|
h('input', {
|
|
19
19
|
class: 'hidden' + (className || ''),
|
|
20
|
-
...formAttrs.value
|
|
21
|
-
...formDomProps.value
|
|
20
|
+
...formAttrs.value
|
|
22
21
|
})
|
|
23
22
|
)
|
|
24
23
|
}
|
|
@@ -3,6 +3,8 @@ import { ref, watch, onBeforeMount, onMounted, onBeforeUnmount, getCurrentInstan
|
|
|
3
3
|
import History from '../../history.js'
|
|
4
4
|
import { vmHasRouter } from '../../utils/private/vm.js'
|
|
5
5
|
|
|
6
|
+
let counter = 0
|
|
7
|
+
|
|
6
8
|
export const useFullscreenProps = {
|
|
7
9
|
fullscreen: Boolean,
|
|
8
10
|
noRouteFullscreenExit: Boolean
|
|
@@ -50,7 +52,11 @@ export default function () {
|
|
|
50
52
|
container = proxy.$el.parentNode
|
|
51
53
|
container.replaceChild(fullscreenFillerNode, proxy.$el)
|
|
52
54
|
document.body.appendChild(proxy.$el)
|
|
53
|
-
|
|
55
|
+
|
|
56
|
+
counter++
|
|
57
|
+
if (counter === 1) {
|
|
58
|
+
document.body.classList.add('q-body--fullscreen-mixin')
|
|
59
|
+
}
|
|
54
60
|
|
|
55
61
|
historyEntry = {
|
|
56
62
|
handler: exitFullscreen
|
|
@@ -69,11 +75,16 @@ export default function () {
|
|
|
69
75
|
}
|
|
70
76
|
|
|
71
77
|
container.replaceChild(proxy.$el, fullscreenFillerNode)
|
|
72
|
-
document.body.classList.remove('q-body--fullscreen-mixin')
|
|
73
78
|
inFullscreen.value = false
|
|
74
79
|
|
|
75
|
-
|
|
76
|
-
|
|
80
|
+
counter = Math.max(0, counter - 1)
|
|
81
|
+
|
|
82
|
+
if (counter === 0) {
|
|
83
|
+
document.body.classList.remove('q-body--fullscreen-mixin')
|
|
84
|
+
|
|
85
|
+
if (proxy.$el.scrollIntoView !== void 0) {
|
|
86
|
+
setTimeout(() => { proxy.$el.scrollIntoView() })
|
|
87
|
+
}
|
|
77
88
|
}
|
|
78
89
|
}
|
|
79
90
|
|
|
@@ -79,6 +79,7 @@ function isSameRouteLocationParams (a, b) {
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
export const useRouterLinkProps = {
|
|
82
|
+
// router-link
|
|
82
83
|
to: [ String, Object ],
|
|
83
84
|
replace: Boolean,
|
|
84
85
|
exact: Boolean,
|
|
@@ -90,23 +91,33 @@ export const useRouterLinkProps = {
|
|
|
90
91
|
type: String,
|
|
91
92
|
default: 'q-router-link--exact-active'
|
|
92
93
|
},
|
|
94
|
+
|
|
95
|
+
// regular <a> link
|
|
96
|
+
href: String,
|
|
97
|
+
target: String,
|
|
98
|
+
|
|
99
|
+
// state
|
|
93
100
|
disable: Boolean
|
|
94
101
|
}
|
|
95
102
|
|
|
96
|
-
|
|
103
|
+
// external props: type, tag
|
|
104
|
+
|
|
105
|
+
export default function (fallbackTag) {
|
|
97
106
|
const vm = getCurrentInstance()
|
|
98
|
-
const { props,
|
|
107
|
+
const { props, proxy } = vm
|
|
99
108
|
|
|
100
109
|
const hasRouter = vmHasRouter(vm)
|
|
110
|
+
const hasHrefLink = computed(() => props.disable !== true && props.href !== void 0)
|
|
101
111
|
|
|
102
|
-
const
|
|
112
|
+
const hasRouterLinkProps = computed(() =>
|
|
103
113
|
hasRouter === true
|
|
104
114
|
&& props.disable !== true
|
|
115
|
+
&& hasHrefLink.value !== true
|
|
105
116
|
&& props.to !== void 0 && props.to !== null && props.to !== ''
|
|
106
117
|
)
|
|
107
118
|
|
|
108
119
|
const linkRoute = computed(() => {
|
|
109
|
-
if (
|
|
120
|
+
if (hasRouterLinkProps.value === true) {
|
|
110
121
|
try { return proxy.$router.resolve(props.to) }
|
|
111
122
|
catch (err) {}
|
|
112
123
|
}
|
|
@@ -114,16 +125,33 @@ export default function () {
|
|
|
114
125
|
return null
|
|
115
126
|
})
|
|
116
127
|
|
|
117
|
-
const
|
|
128
|
+
const hasRouterLink = computed(() => linkRoute.value !== null)
|
|
129
|
+
const hasLink = computed(() => hasHrefLink.value === true || hasRouterLink.value === true)
|
|
118
130
|
|
|
119
131
|
const linkTag = computed(() => (
|
|
120
|
-
hasLink.value === true
|
|
132
|
+
props.type === 'a' || hasLink.value === true
|
|
121
133
|
? 'a'
|
|
122
|
-
: (props.tag || 'div')
|
|
134
|
+
: (props.tag || fallbackTag || 'div')
|
|
135
|
+
))
|
|
136
|
+
|
|
137
|
+
const linkProps = computed(() => (
|
|
138
|
+
hasHrefLink.value === true
|
|
139
|
+
? {
|
|
140
|
+
href: props.href,
|
|
141
|
+
target: props.target
|
|
142
|
+
}
|
|
143
|
+
: (
|
|
144
|
+
hasRouterLink.value === true
|
|
145
|
+
? {
|
|
146
|
+
href: linkRoute.value.href,
|
|
147
|
+
target: props.target
|
|
148
|
+
}
|
|
149
|
+
: {}
|
|
150
|
+
)
|
|
123
151
|
))
|
|
124
152
|
|
|
125
153
|
const linkActiveIndex = computed(() => {
|
|
126
|
-
if (
|
|
154
|
+
if (hasRouterLink.value === false) {
|
|
127
155
|
return null
|
|
128
156
|
}
|
|
129
157
|
|
|
@@ -170,7 +198,7 @@ export default function () {
|
|
|
170
198
|
})
|
|
171
199
|
|
|
172
200
|
const linkIsActive = computed(() =>
|
|
173
|
-
|
|
201
|
+
hasRouterLink.value === true
|
|
174
202
|
&& linkActiveIndex.value > -1
|
|
175
203
|
&& includesParams(proxy.$route.params, linkRoute.value.params)
|
|
176
204
|
)
|
|
@@ -182,7 +210,7 @@ export default function () {
|
|
|
182
210
|
)
|
|
183
211
|
|
|
184
212
|
const linkClass = computed(() => (
|
|
185
|
-
|
|
213
|
+
hasRouterLink.value === true
|
|
186
214
|
? (
|
|
187
215
|
linkIsExactActive.value === true
|
|
188
216
|
? ` ${ props.exactActiveClass } ${ props.activeClass }`
|
|
@@ -195,18 +223,8 @@ export default function () {
|
|
|
195
223
|
: ''
|
|
196
224
|
))
|
|
197
225
|
|
|
198
|
-
const linkProps = computed(() => (
|
|
199
|
-
hasLink.value === true
|
|
200
|
-
? {
|
|
201
|
-
href: linkRoute.value.href,
|
|
202
|
-
target: attrs.target,
|
|
203
|
-
role: 'link'
|
|
204
|
-
}
|
|
205
|
-
: {}
|
|
206
|
-
))
|
|
207
|
-
|
|
208
226
|
// should match RouterLink from Vue Router
|
|
209
|
-
function
|
|
227
|
+
function navigateToRouterLink (e) {
|
|
210
228
|
if (
|
|
211
229
|
// component is not disabled
|
|
212
230
|
props.disable === true
|
|
@@ -222,7 +240,7 @@ export default function () {
|
|
|
222
240
|
|| (e.button !== undefined && e.button !== 0)
|
|
223
241
|
|
|
224
242
|
// don't redirect if it should open in a new window
|
|
225
|
-
||
|
|
243
|
+
|| props.target === '_blank'
|
|
226
244
|
) {
|
|
227
245
|
return false
|
|
228
246
|
}
|
|
@@ -234,7 +252,10 @@ export default function () {
|
|
|
234
252
|
}
|
|
235
253
|
|
|
236
254
|
return {
|
|
255
|
+
hasRouterLink,
|
|
256
|
+
hasHrefLink,
|
|
237
257
|
hasLink,
|
|
258
|
+
|
|
238
259
|
linkTag,
|
|
239
260
|
linkRoute,
|
|
240
261
|
linkIsActive,
|
|
@@ -242,6 +263,6 @@ export default function () {
|
|
|
242
263
|
linkClass,
|
|
243
264
|
linkProps,
|
|
244
265
|
|
|
245
|
-
|
|
266
|
+
navigateToRouterLink
|
|
246
267
|
}
|
|
247
268
|
}
|
|
@@ -2,38 +2,54 @@
|
|
|
2
2
|
"props": {
|
|
3
3
|
"to": {
|
|
4
4
|
"type": [ "String", "Object" ],
|
|
5
|
-
"desc": "Equivalent to Vue Router <router-link> 'to' property",
|
|
5
|
+
"desc": "Equivalent to Vue Router <router-link> 'to' property; Superseeded by 'href' prop if used",
|
|
6
6
|
"examples": [
|
|
7
7
|
"/home/dashboard",
|
|
8
8
|
":to=\"{ name: 'my-route-name' }\""
|
|
9
9
|
],
|
|
10
|
-
"category": "
|
|
10
|
+
"category": "navigation"
|
|
11
11
|
},
|
|
12
12
|
|
|
13
13
|
"exact": {
|
|
14
14
|
"type": "Boolean",
|
|
15
|
-
"desc": "Equivalent to Vue Router <router-link> 'exact' property",
|
|
16
|
-
"category": "
|
|
15
|
+
"desc": "Equivalent to Vue Router <router-link> 'exact' property; Superseeded by 'href' prop if used",
|
|
16
|
+
"category": "navigation"
|
|
17
17
|
},
|
|
18
18
|
|
|
19
19
|
"replace": {
|
|
20
20
|
"type": "Boolean",
|
|
21
|
-
"desc": "Equivalent to Vue Router <router-link> 'replace' property",
|
|
22
|
-
"category": "
|
|
21
|
+
"desc": "Equivalent to Vue Router <router-link> 'replace' property; Superseeded by 'href' prop if used",
|
|
22
|
+
"category": "navigation"
|
|
23
23
|
},
|
|
24
24
|
|
|
25
25
|
"active-class": {
|
|
26
26
|
"type": "String",
|
|
27
|
-
"desc": "Equivalent to Vue Router <router-link> 'active-class' property",
|
|
27
|
+
"desc": "Equivalent to Vue Router <router-link> 'active-class' property; Superseeded by 'href' prop if used",
|
|
28
28
|
"examples": [ "my-active-class" ],
|
|
29
|
-
"category": "
|
|
29
|
+
"category": "navigation"
|
|
30
30
|
},
|
|
31
31
|
|
|
32
32
|
"exact-active-class": {
|
|
33
33
|
"type": "String",
|
|
34
|
-
"desc": "Equivalent to Vue Router <router-link> 'active-class' property",
|
|
34
|
+
"desc": "Equivalent to Vue Router <router-link> 'active-class' property; Superseeded by 'href' prop if used",
|
|
35
35
|
"examples": [ "my-exact-active-class" ],
|
|
36
|
-
"category": "
|
|
36
|
+
"category": "navigation"
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
"href": {
|
|
40
|
+
"type": "String",
|
|
41
|
+
"desc": "Native <a> link href attribute; Has priority over the 'to'/'exact'/'replace'/'active-class'/'exact-active-class' props",
|
|
42
|
+
"examples": [ "http://quasar.dev" ],
|
|
43
|
+
"category": "navigation",
|
|
44
|
+
"addedIn": "v2.4"
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
"target": {
|
|
48
|
+
"type": "String",
|
|
49
|
+
"desc": "Native <a> link target attribute; Use it only along with 'href' prop; Has priority over the 'to'/'exact'/'replace'/'active-class'/'exact-active-class' props",
|
|
50
|
+
"examples": [ "_blank", "_self", "_parent", "_top" ],
|
|
51
|
+
"category": "navigation",
|
|
52
|
+
"addedIn": "v2.4"
|
|
37
53
|
},
|
|
38
54
|
|
|
39
55
|
"disable": {
|
|
@@ -12,17 +12,17 @@ export default function (attrs, vnode) {
|
|
|
12
12
|
const attributes = {}
|
|
13
13
|
const listeners = {}
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
for (const key in attrs) {
|
|
16
16
|
if (key !== 'class' && key !== 'style' && listenerRE.test(key) === false) {
|
|
17
17
|
attributes[ key ] = attrs[ key ]
|
|
18
18
|
}
|
|
19
|
-
}
|
|
19
|
+
}
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
for (const key in vnode.props) {
|
|
22
22
|
if (listenerRE.test(key) === true) {
|
|
23
23
|
listeners[ key ] = vnode.props[ key ]
|
|
24
24
|
}
|
|
25
|
-
}
|
|
25
|
+
}
|
|
26
26
|
|
|
27
27
|
acc.attributes.value = attributes
|
|
28
28
|
acc.listeners.value = listeners
|
|
@@ -2,6 +2,8 @@ import { ref, computed, watch, onBeforeUnmount, getCurrentInstance } from 'vue'
|
|
|
2
2
|
|
|
3
3
|
import useFormChild from '../use-form-child.js'
|
|
4
4
|
import { testPattern } from '../../utils/patterns.js'
|
|
5
|
+
import { debounce } from '../../utils.js'
|
|
6
|
+
import { injectProp } from '../../utils/private/inject-obj-prop.js'
|
|
5
7
|
|
|
6
8
|
const lazyRulesValues = [ true, false, 'ondemand' ]
|
|
7
9
|
|
|
@@ -35,7 +37,8 @@ export default function (focused, innerLoading) {
|
|
|
35
37
|
let validateIndex = 0, unwatchRules
|
|
36
38
|
|
|
37
39
|
const hasRules = computed(() =>
|
|
38
|
-
props.
|
|
40
|
+
props.disable !== true
|
|
41
|
+
&& props.rules !== void 0
|
|
39
42
|
&& props.rules !== null
|
|
40
43
|
&& props.rules.length > 0
|
|
41
44
|
)
|
|
@@ -44,7 +47,7 @@ export default function (focused, innerLoading) {
|
|
|
44
47
|
props.error === true || innerError.value === true
|
|
45
48
|
)
|
|
46
49
|
|
|
47
|
-
const
|
|
50
|
+
const errorMessage = computed(() => (
|
|
48
51
|
typeof props.errorMessage === 'string' && props.errorMessage.length > 0
|
|
49
52
|
? props.errorMessage
|
|
50
53
|
: innerErrorMessage.value
|
|
@@ -69,15 +72,16 @@ export default function (focused, innerLoading) {
|
|
|
69
72
|
}, { immediate: true })
|
|
70
73
|
|
|
71
74
|
watch(focused, val => {
|
|
72
|
-
if (
|
|
73
|
-
if (
|
|
74
|
-
|
|
75
|
-
isDirtyModel.value = false
|
|
76
|
-
}
|
|
75
|
+
if (val === true) {
|
|
76
|
+
if (isDirtyModel.value === null) {
|
|
77
|
+
isDirtyModel.value = false
|
|
77
78
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
}
|
|
80
|
+
else if (isDirtyModel.value === false) {
|
|
81
|
+
isDirtyModel.value = true
|
|
82
|
+
|
|
83
|
+
if (hasRules.value === true && props.lazyRules !== 'ondemand') {
|
|
84
|
+
debouncedValidate()
|
|
81
85
|
}
|
|
82
86
|
}
|
|
83
87
|
})
|
|
@@ -88,6 +92,7 @@ export default function (focused, innerLoading) {
|
|
|
88
92
|
isDirtyModel.value = null
|
|
89
93
|
innerError.value = false
|
|
90
94
|
innerErrorMessage.value = null
|
|
95
|
+
debouncedValidate.cancel()
|
|
91
96
|
}
|
|
92
97
|
|
|
93
98
|
/*
|
|
@@ -189,25 +194,26 @@ export default function (focused, innerLoading) {
|
|
|
189
194
|
&& props.lazyRules !== 'ondemand'
|
|
190
195
|
&& (isDirtyModel.value === true || (props.lazyRules !== true && changedRules !== true))
|
|
191
196
|
) {
|
|
192
|
-
|
|
197
|
+
debouncedValidate()
|
|
193
198
|
}
|
|
194
199
|
}
|
|
195
200
|
|
|
201
|
+
const debouncedValidate = debounce(validate, 0)
|
|
202
|
+
|
|
196
203
|
onBeforeUnmount(() => {
|
|
197
204
|
unwatchRules !== void 0 && unwatchRules()
|
|
205
|
+
debouncedValidate.cancel()
|
|
198
206
|
})
|
|
199
207
|
|
|
200
208
|
// expose public methods & props
|
|
201
209
|
Object.assign(proxy, { resetValidation, validate })
|
|
202
|
-
|
|
203
|
-
get: () => hasError.value
|
|
204
|
-
})
|
|
210
|
+
injectProp(proxy, 'hasError', () => hasError.value)
|
|
205
211
|
|
|
206
212
|
return {
|
|
207
213
|
isDirtyModel,
|
|
208
214
|
hasRules,
|
|
209
215
|
hasError,
|
|
210
|
-
|
|
216
|
+
errorMessage,
|
|
211
217
|
|
|
212
218
|
validate,
|
|
213
219
|
resetValidation
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
|
|
29
29
|
"rules": {
|
|
30
30
|
"type": "Array",
|
|
31
|
+
"tsType": "ValidationRule",
|
|
31
32
|
"desc": "Array of Functions/Strings; If String, then it must be a name of one of the embedded validation rules",
|
|
32
33
|
"examples": [
|
|
33
34
|
":rules=\"[ val => val.length <= 3 || 'Please use maximum 3 characters' ]\"",
|
|
@@ -69,6 +69,11 @@
|
|
|
69
69
|
max-width: 100vw
|
|
70
70
|
max-height: 100vh
|
|
71
71
|
|
|
72
|
+
body.q-ios-padding .fullscreen
|
|
73
|
+
padding-top: $ios-statusbar-height !important
|
|
74
|
+
padding-top: env(safe-area-inset-top) !important
|
|
75
|
+
padding-bottom: env(safe-area-inset-bottom) !important
|
|
76
|
+
|
|
72
77
|
.absolute-full, .fullscreen, .fixed-full
|
|
73
78
|
top: 0
|
|
74
79
|
right: 0
|
package/src/icon-set.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import defineReactivePlugin from './utils/private/define-reactive-plugin.js'
|
|
2
2
|
import materialIcons from '../icon-set/material-icons.js'
|
|
3
|
+
import { injectProp } from './utils/private/inject-obj-prop.js'
|
|
3
4
|
|
|
4
5
|
const Plugin = defineReactivePlugin({
|
|
5
6
|
iconMapFn: null,
|
|
@@ -42,10 +43,7 @@ const Plugin = defineReactivePlugin({
|
|
|
42
43
|
|
|
43
44
|
$q.iconSet = this.__icons
|
|
44
45
|
|
|
45
|
-
|
|
46
|
-
get: () => this.iconMapFn,
|
|
47
|
-
set: val => { this.iconMapFn = val }
|
|
48
|
-
})
|
|
46
|
+
injectProp($q, 'iconMapFn', () => this.iconMapFn, val => { this.iconMapFn = val })
|
|
49
47
|
|
|
50
48
|
if (this.__installed === true) {
|
|
51
49
|
iconSet !== void 0 && this.set(iconSet)
|