quasar 1.20.2 → 1.21.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/QBreadcrumbsEl.json +53 -0
- package/dist/api/QBtn.json +42 -5
- package/dist/api/QBtnDropdown.json +1 -1
- package/dist/api/QChip.json +1 -1
- package/dist/api/QDialog.json +6 -0
- package/dist/api/QExpansionItem.json +1 -1
- package/dist/api/QItem.json +53 -0
- package/dist/api/QRating.json +13 -0
- package/dist/api/QRouteTab.json +6 -2
- package/dist/babel-transforms/imports.js +2 -12
- package/dist/icon-set/bootstrap-icons.umd.min.js +1 -1
- package/dist/icon-set/eva-icons.umd.min.js +1 -1
- package/dist/icon-set/fontawesome-v5-pro.umd.min.js +1 -1
- package/dist/icon-set/fontawesome-v5.umd.min.js +1 -1
- package/dist/icon-set/fontawesome-v6-pro.umd.min.js +1 -1
- package/dist/icon-set/fontawesome-v6.umd.min.js +1 -1
- package/dist/icon-set/ionicons-v4.umd.min.js +1 -1
- package/dist/icon-set/line-awesome.umd.min.js +1 -1
- package/dist/icon-set/material-icons-outlined.umd.min.js +1 -1
- package/dist/icon-set/material-icons-round.umd.min.js +1 -1
- package/dist/icon-set/material-icons-sharp.umd.min.js +1 -1
- package/dist/icon-set/material-icons.umd.min.js +1 -1
- package/dist/icon-set/material-symbols-outlined.umd.min.js +1 -1
- package/dist/icon-set/material-symbols-rounded.umd.min.js +1 -1
- package/dist/icon-set/material-symbols-sharp.umd.min.js +1 -1
- package/dist/icon-set/mdi-v3.umd.min.js +1 -1
- package/dist/icon-set/mdi-v4.umd.min.js +1 -1
- package/dist/icon-set/mdi-v5.umd.min.js +1 -1
- package/dist/icon-set/mdi-v6.umd.min.js +1 -1
- package/dist/icon-set/svg-bootstrap-icons.umd.min.js +1 -1
- package/dist/icon-set/svg-eva-icons.umd.min.js +1 -1
- package/dist/icon-set/svg-fontawesome-v5.umd.min.js +1 -1
- package/dist/icon-set/svg-fontawesome-v6.umd.min.js +2 -2
- package/dist/icon-set/svg-ionicons-v4.umd.min.js +1 -1
- package/dist/icon-set/svg-ionicons-v5.umd.min.js +1 -1
- package/dist/icon-set/svg-ionicons-v6.umd.min.js +1 -1
- package/dist/icon-set/svg-line-awesome.umd.min.js +1 -1
- package/dist/icon-set/svg-material-icons-outlined.umd.min.js +1 -1
- package/dist/icon-set/svg-material-icons-round.umd.min.js +1 -1
- package/dist/icon-set/svg-material-icons-sharp.umd.min.js +1 -1
- package/dist/icon-set/svg-material-icons.umd.min.js +1 -1
- package/dist/icon-set/svg-material-symbols-outlined.umd.min.js +2 -2
- package/dist/icon-set/svg-material-symbols-rounded.umd.min.js +2 -2
- package/dist/icon-set/svg-material-symbols-sharp.umd.min.js +2 -2
- package/dist/icon-set/svg-mdi-v4.umd.min.js +1 -1
- package/dist/icon-set/svg-mdi-v5.umd.min.js +1 -1
- package/dist/icon-set/svg-mdi-v6.umd.min.js +1 -1
- package/dist/icon-set/svg-themify.umd.min.js +1 -1
- package/dist/icon-set/themify.umd.min.js +1 -1
- package/dist/lang/ar.umd.min.js +1 -1
- package/dist/lang/az-latn.umd.min.js +1 -1
- package/dist/lang/bg.umd.min.js +1 -1
- package/dist/lang/ca.umd.min.js +1 -1
- package/dist/lang/cs.umd.min.js +1 -1
- package/dist/lang/da.umd.min.js +1 -1
- package/dist/lang/de.umd.min.js +1 -1
- package/dist/lang/el.umd.min.js +1 -1
- package/dist/lang/en-gb.umd.min.js +1 -1
- package/dist/lang/en-us.umd.min.js +1 -1
- package/dist/lang/eo.umd.min.js +1 -1
- package/dist/lang/es.umd.min.js +1 -1
- package/dist/lang/et.umd.min.js +1 -1
- package/dist/lang/eu.umd.min.js +1 -1
- package/dist/lang/fa-ir.umd.min.js +1 -1
- package/dist/lang/fa.umd.min.js +1 -1
- package/dist/lang/fi.umd.min.js +1 -1
- package/dist/lang/fr.umd.min.js +1 -1
- package/dist/lang/gn.umd.min.js +1 -1
- package/dist/lang/he.umd.min.js +1 -1
- package/dist/lang/hr.umd.min.js +1 -1
- package/dist/lang/hu.umd.min.js +1 -1
- package/dist/lang/id.umd.min.js +1 -1
- package/dist/lang/is.umd.min.js +1 -1
- package/dist/lang/it.umd.min.js +1 -1
- package/dist/lang/ja.umd.min.js +1 -1
- package/dist/lang/km.umd.min.js +1 -1
- package/dist/lang/ko-kr.umd.min.js +1 -1
- package/dist/lang/kur-ckb.umd.min.js +1 -1
- package/dist/lang/kz.umd.min.js +1 -1
- package/dist/lang/lu.umd.min.js +1 -1
- package/dist/lang/lv.umd.min.js +1 -1
- package/dist/lang/ml.umd.min.js +1 -1
- package/dist/lang/mm.umd.min.js +1 -1
- package/dist/lang/ms.umd.min.js +1 -1
- package/dist/lang/my.umd.min.js +1 -1
- package/dist/lang/nb-no.umd.min.js +1 -1
- package/dist/lang/nl.umd.min.js +2 -2
- package/dist/lang/pl.umd.min.js +1 -1
- package/dist/lang/pt-br.umd.min.js +1 -1
- package/dist/lang/pt.umd.min.js +1 -1
- package/dist/lang/ro.umd.min.js +1 -1
- package/dist/lang/ru.umd.min.js +1 -1
- package/dist/lang/sk.umd.min.js +1 -1
- package/dist/lang/sl.umd.min.js +1 -1
- package/dist/lang/sm.umd.min.js +1 -1
- package/dist/lang/sr.umd.min.js +1 -1
- package/dist/lang/sv.umd.min.js +1 -1
- package/dist/lang/ta.umd.min.js +1 -1
- package/dist/lang/th.umd.min.js +1 -1
- package/dist/lang/tr.umd.min.js +1 -1
- package/dist/lang/ug.umd.min.js +1 -1
- package/dist/lang/uk.umd.min.js +1 -1
- package/dist/lang/uz-Cyrl.umd.min.js +1 -1
- package/dist/lang/uz-Latn.umd.min.js +1 -1
- package/dist/lang/vi.umd.min.js +1 -1
- package/dist/lang/zh-hans.umd.min.js +1 -1
- package/dist/lang/zh-hant.umd.min.js +1 -1
- package/dist/quasar.addon.css +1 -1
- package/dist/quasar.addon.rtl.css +1 -1
- package/dist/quasar.common.js +2 -2
- package/dist/quasar.css +43 -288
- package/dist/quasar.esm.js +2 -2
- package/dist/quasar.ie.polyfills.js +1 -1
- package/dist/quasar.ie.polyfills.umd.min.js +1 -1
- package/dist/quasar.min.css +1 -1
- package/dist/quasar.rtl.css +46 -408
- package/dist/quasar.rtl.min.css +1 -1
- package/dist/quasar.sass +3 -7
- package/dist/quasar.styl +3 -7
- package/dist/quasar.umd.js +1062 -867
- package/dist/quasar.umd.min.js +2 -2
- package/dist/quasar.umd.modern.js +1017 -854
- package/dist/quasar.umd.modern.min.js +2 -2
- package/dist/types/index.d.ts +8 -0
- package/dist/types/utils/run-sequential-promises.d.ts +1 -1
- package/dist/vetur/quasar-attributes.json +8 -0
- package/dist/vetur/quasar-tags.json +3 -1
- package/dist/web-types/web-types.json +66 -5
- package/lang/nl.js +2 -2
- package/package.json +1 -1
- package/src/body.js +1 -1
- package/src/components/avatar/QAvatar.js +1 -1
- package/src/components/badge/QBadge.js +1 -1
- package/src/components/banner/QBanner.js +1 -1
- package/src/components/bar/QBar.js +1 -1
- package/src/components/breadcrumbs/QBreadcrumbs.js +1 -1
- package/src/components/breadcrumbs/QBreadcrumbsEl.js +7 -4
- package/src/components/breadcrumbs/QBreadcrumbsEl.json +56 -0
- package/src/components/btn/QBtn.js +7 -29
- package/src/components/btn/QBtn.json +43 -5
- package/src/components/btn-dropdown/QBtnDropdown.js +2 -2
- package/src/components/btn-dropdown/QBtnDropdown.json +1 -1
- package/src/components/btn-group/QBtnGroup.js +1 -1
- package/src/components/btn-toggle/QBtnToggle.js +1 -1
- package/src/components/card/QCard.js +1 -1
- package/src/components/card/QCardActions.js +1 -1
- package/src/components/card/QCardSection.js +1 -1
- package/src/components/carousel/QCarousel.js +2 -2
- package/src/components/carousel/QCarouselControl.js +1 -1
- package/src/components/carousel/QCarouselSlide.js +1 -1
- package/src/components/checkbox/QCheckbox.js +1 -1
- package/src/components/chip/QChip.js +2 -2
- package/src/components/chip/QChip.json +1 -1
- package/src/components/circular-progress/QCircularProgress.js +1 -1
- package/src/components/color/QColor.js +1 -1
- package/src/components/date/QDate.js +3 -3
- package/src/components/dialog/QDialog.js +22 -7
- package/src/components/dialog/QDialog.json +7 -0
- package/src/components/dialog-bottom-sheet/BottomSheet.js +1 -1
- package/src/components/dialog-plugin/DialogPlugin.js +2 -2
- package/src/components/drawer/QDrawer.js +13 -7
- package/src/components/editor/QEditor.js +2 -2
- package/src/components/editor/editor-utils.js +2 -2
- package/src/components/expansion-item/QExpansionItem.js +29 -14
- package/src/components/expansion-item/QExpansionItem.json +1 -1
- package/src/components/fab/QFab.js +2 -2
- package/src/components/fab/QFabAction.js +1 -1
- package/src/components/field/QField.js +2 -2
- package/src/components/file/QFile.js +1 -1
- package/src/components/footer/QFooter.js +2 -2
- package/src/components/form/QForm.js +3 -3
- package/src/components/header/QHeader.js +2 -2
- package/src/components/icon/QIcon.js +1 -1
- package/src/components/img/QImg.js +1 -1
- package/src/components/infinite-scroll/QInfiniteScroll.js +1 -1
- package/src/components/input/QInput.js +1 -1
- package/src/components/intersection/QIntersection.js +1 -1
- package/src/components/item/QItem.js +39 -33
- package/src/components/item/QItem.json +56 -0
- package/src/components/item/QItemLabel.js +1 -1
- package/src/components/item/QItemSection.js +1 -1
- package/src/components/item/QList.js +1 -1
- package/src/components/knob/QKnob.js +2 -2
- package/src/components/layout/QLayout.js +2 -2
- package/src/components/linear-progress/QLinearProgress.js +1 -1
- package/src/components/markup-table/QMarkupTable.js +1 -1
- package/src/components/menu/ClickOutside.js +1 -1
- package/src/components/menu/QMenu.js +16 -7
- package/src/components/no-ssr/QNoSsr.js +1 -1
- package/src/components/option-group/QOptionGroup.js +1 -1
- package/src/components/page/QPage.js +1 -1
- package/src/components/page/QPageContainer.js +1 -1
- package/src/components/page-sticky/QPageSticky.js +1 -1
- package/src/components/pagination/QPagination.js +2 -2
- package/src/components/parallax/QParallax.js +1 -1
- package/src/components/popup-edit/QPopupEdit.js +6 -12
- package/src/components/popup-proxy/QPopupProxy.js +1 -1
- package/src/components/pull-to-refresh/QPullToRefresh.js +1 -1
- package/src/components/radio/QRadio.js +5 -4
- package/src/components/rating/QRating.js +46 -15
- package/src/components/rating/QRating.json +11 -0
- package/src/components/resize-observer/QResizeObserver.js +1 -1
- package/src/components/responsive/QResponsive.js +1 -1
- package/src/components/scroll-area/QScrollArea.js +2 -2
- package/src/components/select/QSelect.js +3 -3
- package/src/components/skeleton/QSkeleton.js +1 -1
- package/src/components/slide-item/QSlideItem.js +2 -2
- package/src/components/slide-transition/QSlideTransition.js +2 -2
- package/src/components/splitter/QSplitter.js +2 -2
- package/src/components/stepper/QStep.js +2 -2
- package/src/components/stepper/QStepper.js +2 -2
- package/src/components/stepper/QStepperNavigation.js +1 -1
- package/src/components/stepper/StepHeader.js +1 -1
- package/src/components/tab-panels/QTabPanel.js +1 -1
- package/src/components/table/QTable.js +1 -1
- package/src/components/table/QTd.js +1 -1
- package/src/components/table/QTh.js +1 -1
- package/src/components/table/QTr.js +1 -1
- package/src/components/table/table-body.js +21 -32
- package/src/components/table/table-bottom.js +1 -1
- package/src/components/table/table-header.js +9 -9
- package/src/components/table/table-sort.js +1 -1
- package/src/components/tabs/QRouteTab.js +10 -120
- package/src/components/tabs/QRouteTab.json +7 -2
- package/src/components/tabs/QTab.js +112 -75
- package/src/components/tabs/QTabs.js +411 -329
- package/src/components/tabs/QTabs.sass +2 -7
- package/src/components/tabs/QTabs.styl +2 -7
- package/src/components/time/QTime.js +2 -2
- package/src/components/timeline/QTimeline.js +1 -1
- package/src/components/timeline/QTimelineEntry.js +1 -1
- package/src/components/toolbar/QToolbar.js +1 -1
- package/src/components/toolbar/QToolbarTitle.js +1 -1
- package/src/components/tooltip/QTooltip.js +19 -15
- package/src/components/tree/QTree.js +17 -15
- package/src/components/uploader/QUploaderBase.js +1 -1
- package/src/components/virtual-scroll/QVirtualScroll.js +1 -1
- package/src/directives/ClosePopup.js +1 -1
- package/src/directives/GoBack.js +1 -1
- package/src/directives/Ripple.js +1 -1
- package/src/directives/TouchHold.js +2 -2
- package/src/directives/TouchPan.js +4 -4
- package/src/directives/TouchRepeat.js +3 -3
- package/src/directives/TouchSwipe.js +3 -3
- package/src/mixins/anchor.js +2 -2
- package/src/mixins/attrs.js +1 -1
- package/src/mixins/btn.js +4 -3
- package/src/mixins/checkbox.js +4 -3
- package/src/mixins/datetime.js +1 -1
- package/src/mixins/file.js +1 -1
- package/src/mixins/listeners.js +1 -1
- package/src/mixins/mask.js +1 -1
- package/src/mixins/model-toggle.js +5 -7
- package/src/mixins/panel.js +2 -2
- package/src/mixins/portal.js +1 -1
- package/src/mixins/router-link.js +164 -38
- package/src/mixins/timeout.js +57 -26
- package/src/plugins/BottomSheet.js +1 -1
- package/src/plugins/BottomSheet.json +1 -1
- package/src/plugins/Dialog.js +1 -1
- package/src/plugins/Dialog.json +1 -1
- package/src/plugins/Loading.js +1 -1
- package/src/plugins/LocalStorage.js +1 -1
- package/src/plugins/LocalStorage.json +1 -1
- package/src/plugins/SessionStorage.js +1 -1
- package/src/plugins/SessionStorage.json +1 -1
- package/src/utils/date.js +1 -1
- package/src/utils/extend.js +15 -19
- package/src/utils/{cache.js → private/cache.js} +1 -1
- package/src/utils/{date-persian.js → private/date-persian.js} +0 -0
- package/src/utils/{escape-key.js → private/escape-key.js} +0 -0
- package/src/utils/{focus-manager.js → private/focus-manager.js} +0 -0
- package/src/utils/{global-dialog.js → private/global-dialog.js} +1 -1
- package/src/utils/{global-dialog.json → private/global-dialog.json} +0 -0
- package/src/utils/private/inject-obj-prop.js +15 -0
- package/src/utils/{key-composition.js → private/key-composition.js} +0 -0
- package/src/utils/{position-engine.js → private/position-engine.js} +2 -2
- package/src/utils/{selection.js → private/selection.js} +1 -1
- package/src/utils/{slot.js → private/slot.js} +0 -0
- package/src/utils/{sort.js → private/sort.js} +0 -0
- package/src/utils/{touch.js → private/touch.js} +0 -0
- package/src/utils/{vm.js → private/vm.js} +0 -0
- package/src/utils/{web-storage.js → private/web-storage.js} +2 -2
- package/src/utils/{web-storage.json → private/web-storage.json} +0 -0
- package/src/utils/run-sequential-promises.js +1 -1
- package/src/utils.js +4 -4
- package/src/utils/router.js +0 -50
|
@@ -7,9 +7,10 @@ import TimeoutMixin from '../../mixins/timeout.js'
|
|
|
7
7
|
import ListenersMixin from '../../mixins/listeners.js'
|
|
8
8
|
|
|
9
9
|
import { stop, noop } from '../../utils/event.js'
|
|
10
|
-
import { slot } from '../../utils/slot.js'
|
|
11
|
-
import cache from '../../utils/cache.js'
|
|
10
|
+
import { slot } from '../../utils/private/slot.js'
|
|
11
|
+
import cache from '../../utils/private/cache.js'
|
|
12
12
|
import { rtlHasScrollBug } from '../../utils/scroll.js'
|
|
13
|
+
import { injectProp } from '../../utils/private/inject-obj-prop.js'
|
|
13
14
|
|
|
14
15
|
function getIndicatorClass (color, top, vertical) {
|
|
15
16
|
const pos = vertical === true
|
|
@@ -19,44 +20,26 @@ function getIndicatorClass (color, top, vertical) {
|
|
|
19
20
|
return `absolute-${top === true ? pos[0] : pos[1]}${color ? ` text-${color}` : ''}`
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
const alignValues = [ 'left', 'center', 'right', 'justify' ]
|
|
24
|
+
const getDefaultBestScore = () => ({ matchedLen: 0, queryDiff: 9999, hrefLen: 0, exact: false, redirected: true })
|
|
25
|
+
|
|
26
|
+
function hasQueryIncluded (targetQuery, matchingQuery) {
|
|
27
|
+
for (const key in targetQuery) {
|
|
28
|
+
if (targetQuery[ key ] !== matchingQuery[ key ]) {
|
|
29
|
+
return false
|
|
30
|
+
}
|
|
25
31
|
}
|
|
26
|
-
return t2.priorityMatched - t1.priorityMatched
|
|
27
|
-
}
|
|
28
32
|
|
|
29
|
-
|
|
30
|
-
t.selected = false
|
|
31
|
-
return t
|
|
33
|
+
return true
|
|
32
34
|
}
|
|
33
35
|
|
|
34
|
-
const
|
|
35
|
-
bufferFilters = [
|
|
36
|
-
t => t.selected === true && t.exact === true && t.redirected !== true,
|
|
37
|
-
t => t.selected === true && t.exact === true,
|
|
38
|
-
t => t.selected === true && t.redirected !== true,
|
|
39
|
-
t => t.selected === true,
|
|
40
|
-
t => t.exact === true && t.redirected !== true,
|
|
41
|
-
t => t.redirected !== true,
|
|
42
|
-
t => t.exact === true,
|
|
43
|
-
t => true
|
|
44
|
-
],
|
|
45
|
-
bufferFiltersLen = bufferFilters.length
|
|
46
|
-
|
|
47
36
|
export default Vue.extend({
|
|
48
37
|
name: 'QTabs',
|
|
49
38
|
|
|
50
39
|
mixins: [ TimeoutMixin, ListenersMixin ],
|
|
51
40
|
|
|
52
41
|
provide () {
|
|
53
|
-
return {
|
|
54
|
-
tabs: this.tabs,
|
|
55
|
-
__recalculateScroll: this.__recalculateScroll,
|
|
56
|
-
__activateTab: this.__activateTab,
|
|
57
|
-
__activateRoute: this.__activateRoute,
|
|
58
|
-
__onKbdNavigate: this.__onKbdNavigate
|
|
59
|
-
}
|
|
42
|
+
return { $tabs: this }
|
|
60
43
|
},
|
|
61
44
|
|
|
62
45
|
props: {
|
|
@@ -65,7 +48,7 @@ export default Vue.extend({
|
|
|
65
48
|
align: {
|
|
66
49
|
type: String,
|
|
67
50
|
default: 'center',
|
|
68
|
-
validator: v =>
|
|
51
|
+
validator: v => alignValues.includes(v)
|
|
69
52
|
},
|
|
70
53
|
breakpoint: {
|
|
71
54
|
type: [String, Number],
|
|
@@ -99,67 +82,27 @@ export default Vue.extend({
|
|
|
99
82
|
|
|
100
83
|
data () {
|
|
101
84
|
return {
|
|
102
|
-
tabs: {
|
|
103
|
-
current: this.value,
|
|
104
|
-
hasFocus: false,
|
|
105
|
-
activeClass: this.activeClass,
|
|
106
|
-
activeColor: this.activeColor,
|
|
107
|
-
activeBgColor: this.activeBgColor,
|
|
108
|
-
indicatorClass: getIndicatorClass(
|
|
109
|
-
this.indicatorColor,
|
|
110
|
-
this.switchIndicator,
|
|
111
|
-
this.vertical
|
|
112
|
-
),
|
|
113
|
-
narrowIndicator: this.narrowIndicator,
|
|
114
|
-
inlineLabel: this.inlineLabel,
|
|
115
|
-
noCaps: this.noCaps
|
|
116
|
-
},
|
|
117
85
|
scrollable: false,
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
justify: false
|
|
86
|
+
leftArrow: true,
|
|
87
|
+
rightArrow: false,
|
|
88
|
+
justify: false,
|
|
89
|
+
|
|
90
|
+
tabNameList: [],
|
|
91
|
+
|
|
92
|
+
// used by children
|
|
93
|
+
currentModel: this.value,
|
|
94
|
+
hasFocus: false,
|
|
95
|
+
avoidRouteWatcher: false // false | string (uid)
|
|
121
96
|
}
|
|
122
97
|
},
|
|
123
98
|
|
|
124
99
|
watch: {
|
|
125
|
-
|
|
126
|
-
this.
|
|
127
|
-
},
|
|
128
|
-
|
|
129
|
-
activeClass (v) {
|
|
130
|
-
this.tabs.activeClass = v
|
|
131
|
-
},
|
|
132
|
-
|
|
133
|
-
activeColor (v) {
|
|
134
|
-
this.tabs.activeColor = v
|
|
135
|
-
},
|
|
136
|
-
|
|
137
|
-
activeBgColor (v) {
|
|
138
|
-
this.tabs.activeBgColor = v
|
|
139
|
-
},
|
|
140
|
-
|
|
141
|
-
vertical (v) {
|
|
142
|
-
this.tabs.indicatorClass = getIndicatorClass(this.indicatorColor, this.switchIndicator, v)
|
|
143
|
-
},
|
|
144
|
-
|
|
145
|
-
indicatorColor (v) {
|
|
146
|
-
this.tabs.indicatorClass = getIndicatorClass(v, this.switchIndicator, this.vertical)
|
|
147
|
-
},
|
|
148
|
-
|
|
149
|
-
switchIndicator (v) {
|
|
150
|
-
this.tabs.indicatorClass = getIndicatorClass(this.indicatorColor, v, this.vertical)
|
|
151
|
-
},
|
|
152
|
-
|
|
153
|
-
narrowIndicator (v) {
|
|
154
|
-
this.tabs.narrowIndicator = v
|
|
155
|
-
},
|
|
156
|
-
|
|
157
|
-
inlineLabel (v) {
|
|
158
|
-
this.tabs.inlineLabel = v
|
|
100
|
+
isRTL () {
|
|
101
|
+
this.__localUpdateArrows()
|
|
159
102
|
},
|
|
160
103
|
|
|
161
|
-
|
|
162
|
-
this.
|
|
104
|
+
value (name) {
|
|
105
|
+
this.__updateModel({ name, setCurrent: true, skipEmit: true })
|
|
163
106
|
},
|
|
164
107
|
|
|
165
108
|
outsideArrows () {
|
|
@@ -167,32 +110,39 @@ export default Vue.extend({
|
|
|
167
110
|
},
|
|
168
111
|
|
|
169
112
|
arrowsEnabled (v) {
|
|
170
|
-
this.
|
|
113
|
+
this.__localUpdateArrows = v === true
|
|
171
114
|
? this.__updateArrowsFn
|
|
172
115
|
: noop
|
|
173
116
|
|
|
174
117
|
this.__recalculateScroll()
|
|
175
|
-
},
|
|
176
|
-
|
|
177
|
-
isRTL () {
|
|
178
|
-
this.__updateArrows()
|
|
179
118
|
}
|
|
180
119
|
},
|
|
181
120
|
|
|
182
121
|
computed: {
|
|
183
|
-
|
|
184
|
-
|
|
122
|
+
// used by children
|
|
123
|
+
tabProps () {
|
|
124
|
+
return {
|
|
125
|
+
activeClass: this.activeClass,
|
|
126
|
+
activeColor: this.activeColor,
|
|
127
|
+
activeBgColor: this.activeBgColor,
|
|
128
|
+
indicatorClass: getIndicatorClass(
|
|
129
|
+
this.indicatorColor,
|
|
130
|
+
this.switchIndicator,
|
|
131
|
+
this.vertical
|
|
132
|
+
),
|
|
133
|
+
narrowIndicator: this.narrowIndicator,
|
|
134
|
+
inlineLabel: this.inlineLabel,
|
|
135
|
+
noCaps: this.noCaps
|
|
136
|
+
}
|
|
185
137
|
},
|
|
186
138
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
139
|
+
// used by children
|
|
140
|
+
hasActiveTab () {
|
|
141
|
+
return this.tabNameList.some(entry => entry.name === this.currentModel)
|
|
142
|
+
},
|
|
191
143
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
[sides[1]]: this.rightIcon || (this.vertical === true ? this.$q.iconSet.tabs.down : this.$q.iconSet.tabs.right)
|
|
195
|
-
}
|
|
144
|
+
arrowsEnabled () {
|
|
145
|
+
return this.$q.platform.is.desktop === true || this.mobileArrows === true
|
|
196
146
|
},
|
|
197
147
|
|
|
198
148
|
alignClass () {
|
|
@@ -204,7 +154,8 @@ export default Vue.extend({
|
|
|
204
154
|
},
|
|
205
155
|
|
|
206
156
|
classes () {
|
|
207
|
-
return
|
|
157
|
+
return 'q-tabs row no-wrap items-center' +
|
|
158
|
+
` q-tabs--${this.scrollable === true ? '' : 'not-'}scrollable` +
|
|
208
159
|
` q-tabs--${this.vertical === true ? 'vertical' : 'horizontal'}` +
|
|
209
160
|
` q-tabs__arrows--${this.arrowsEnabled === true && this.outsideArrows === true ? 'outside' : 'inside'}` +
|
|
210
161
|
(this.dense === true ? ' q-tabs--dense' : '') +
|
|
@@ -213,7 +164,8 @@ export default Vue.extend({
|
|
|
213
164
|
},
|
|
214
165
|
|
|
215
166
|
innerClass () {
|
|
216
|
-
return
|
|
167
|
+
return 'q-tabs__content row no-wrap items-center self-stretch hide-scrollbar relative-position ' +
|
|
168
|
+
this.alignClass +
|
|
217
169
|
(this.contentClass !== void 0 ? ` ${this.contentClass}` : '') +
|
|
218
170
|
(this.$q.platform.is.mobile === true ? ' scroll' : '')
|
|
219
171
|
},
|
|
@@ -228,41 +180,20 @@ export default Vue.extend({
|
|
|
228
180
|
return this.vertical !== true && this.$q.lang.rtl === true
|
|
229
181
|
},
|
|
230
182
|
|
|
231
|
-
|
|
232
|
-
return this.
|
|
233
|
-
? el => el.scrollTop
|
|
234
|
-
: (
|
|
235
|
-
this.$q.lang.rtl !== true
|
|
236
|
-
? el => el.scrollLeft
|
|
237
|
-
: (
|
|
238
|
-
this.rtlHasScrollBug === true
|
|
239
|
-
? el => el.scrollWidth - el.clientWidth - el.scrollLeft
|
|
240
|
-
: el => 1 - el.scrollLeft
|
|
241
|
-
)
|
|
242
|
-
)
|
|
243
|
-
},
|
|
244
|
-
|
|
245
|
-
__setScrollPosition () {
|
|
246
|
-
return this.vertical === true
|
|
247
|
-
? (el, value) => { el.scrollTop = value }
|
|
248
|
-
: (
|
|
249
|
-
this.$q.lang.rtl !== true
|
|
250
|
-
? (el, value) => { el.scrollLeft = value }
|
|
251
|
-
: (
|
|
252
|
-
this.rtlHasScrollBug === true
|
|
253
|
-
? (el, value) => { el.scrollLeft = el.scrollWidth - el.clientWidth - value }
|
|
254
|
-
: (el, value) => { el.scrollLeft = 1 - value }
|
|
255
|
-
)
|
|
256
|
-
)
|
|
183
|
+
rtlPosCorrection () {
|
|
184
|
+
return rtlHasScrollBug() === false && this.isRTL === true
|
|
257
185
|
},
|
|
258
186
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
187
|
+
// let's speed up execution of time-sensitive scrollTowards()
|
|
188
|
+
// with a computed variable by directly applying the minimal
|
|
189
|
+
// number of instructions on get/set functions
|
|
190
|
+
posFn () {
|
|
191
|
+
return this.rtlPosCorrection === true
|
|
192
|
+
? { get: content => Math.abs(content.scrollLeft), set: (content, pos) => { content.scrollLeft = -pos } }
|
|
262
193
|
: (
|
|
263
|
-
this
|
|
264
|
-
?
|
|
265
|
-
:
|
|
194
|
+
this.vertical === true
|
|
195
|
+
? { get: content => content.scrollTop, set: (content, pos) => { content.scrollTop = pos } }
|
|
196
|
+
: { get: content => content.scrollLeft, set: (content, pos) => { content.scrollLeft = pos } }
|
|
266
197
|
)
|
|
267
198
|
},
|
|
268
199
|
|
|
@@ -277,78 +208,42 @@ export default Vue.extend({
|
|
|
277
208
|
},
|
|
278
209
|
|
|
279
210
|
methods: {
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
this.
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
__onFocusout (e) {
|
|
286
|
-
this.tabs.hasFocus = false
|
|
287
|
-
this.qListeners.focusout !== void 0 && this.$emit('focusout', e)
|
|
288
|
-
},
|
|
289
|
-
|
|
290
|
-
__activateTab (name, setCurrent, skipEmit) {
|
|
291
|
-
if (this.tabs.current !== name) {
|
|
292
|
-
skipEmit !== true && this.$emit('input', name)
|
|
293
|
-
if (setCurrent === true || this.qListeners.input === void 0) {
|
|
294
|
-
this.__animate(this.tabs.current, name)
|
|
295
|
-
this.tabs.current = name
|
|
211
|
+
// used by children too
|
|
212
|
+
__updateModel ({ name, setCurrent, skipEmit }) {
|
|
213
|
+
if (this.currentModel !== name) {
|
|
214
|
+
if (skipEmit !== true && this.qListeners.input !== void 0) {
|
|
215
|
+
this.$emit('input', name)
|
|
296
216
|
}
|
|
297
|
-
}
|
|
298
|
-
},
|
|
299
|
-
|
|
300
|
-
__activateRoute (params) {
|
|
301
|
-
if (this.bufferRoute !== this.$route && this.buffer.length > 0) {
|
|
302
|
-
clearTimeout(this.bufferTimer)
|
|
303
|
-
this.bufferTimer = void 0
|
|
304
|
-
this.buffer.length = 0
|
|
305
|
-
}
|
|
306
|
-
this.bufferRoute = this.$route
|
|
307
217
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
this.
|
|
311
|
-
}
|
|
312
|
-
else {
|
|
313
|
-
this.buffer.push(params)
|
|
218
|
+
if (setCurrent === true || this.qListeners.input === void 0) {
|
|
219
|
+
this.__animate(this.currentModel, name)
|
|
220
|
+
this.currentModel = name
|
|
314
221
|
}
|
|
315
222
|
}
|
|
316
|
-
|
|
317
|
-
if (this.bufferTimer === void 0) {
|
|
318
|
-
this.bufferTimer = setTimeout(() => {
|
|
319
|
-
let tabs = []
|
|
320
|
-
|
|
321
|
-
for (let i = 0; i < bufferFiltersLen && tabs.length === 0; i++) {
|
|
322
|
-
tabs = this.buffer.filter(bufferFilters[i])
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
tabs.sort(bufferPrioritySort)
|
|
326
|
-
this.__activateTab(tabs.length === 0 ? null : tabs[0].name, true)
|
|
327
|
-
this.buffer = this.buffer.map(bufferCleanSelected)
|
|
328
|
-
this.bufferTimer = void 0
|
|
329
|
-
}, 1)
|
|
330
|
-
}
|
|
331
223
|
},
|
|
332
224
|
|
|
333
225
|
__recalculateScroll () {
|
|
334
|
-
this.
|
|
335
|
-
this.
|
|
226
|
+
this.__registerScrollTick(() => {
|
|
227
|
+
this.__updateContainer({
|
|
336
228
|
width: this.$el.offsetWidth,
|
|
337
229
|
height: this.$el.offsetHeight
|
|
338
230
|
})
|
|
339
231
|
})
|
|
340
|
-
|
|
341
|
-
this.__prepareTick()
|
|
342
232
|
},
|
|
343
233
|
|
|
344
234
|
__updateContainer (domSize) {
|
|
235
|
+
// it can be called faster than component being initialized
|
|
236
|
+
// so we need to protect against that case
|
|
237
|
+
// (one example of such case is the docs release notes page)
|
|
238
|
+
if (this.domProps === void 0 || !this.$refs.content) { return }
|
|
239
|
+
|
|
345
240
|
const
|
|
346
|
-
size = domSize[this.domProps.container],
|
|
241
|
+
size = domSize[ this.domProps.container ],
|
|
347
242
|
scrollSize = Math.min(
|
|
348
243
|
this.$refs.content[this.domProps.scroll],
|
|
349
244
|
Array.prototype.reduce.call(
|
|
350
245
|
this.$refs.content.children,
|
|
351
|
-
(acc, el) => acc + (el[this.domProps.content] || 0),
|
|
246
|
+
(acc, el) => acc + (el[ this.domProps.content ] || 0),
|
|
352
247
|
0
|
|
353
248
|
)
|
|
354
249
|
),
|
|
@@ -359,28 +254,28 @@ export default Vue.extend({
|
|
|
359
254
|
}
|
|
360
255
|
|
|
361
256
|
// Arrows need to be updated even if the scroll status was already true
|
|
362
|
-
scroll === true && this
|
|
257
|
+
scroll === true && this.__registerUpdateArrowsTick(this.__localUpdateArrows)
|
|
363
258
|
|
|
364
|
-
const
|
|
259
|
+
const localJustify = size < parseInt(this.breakpoint, 10)
|
|
365
260
|
|
|
366
|
-
if (this.justify !==
|
|
367
|
-
this.justify =
|
|
261
|
+
if (this.justify !== localJustify) {
|
|
262
|
+
this.justify = localJustify
|
|
368
263
|
}
|
|
369
264
|
},
|
|
370
265
|
|
|
371
266
|
__animate (oldName, newName) {
|
|
372
267
|
const
|
|
373
268
|
oldTab = oldName !== void 0 && oldName !== null && oldName !== ''
|
|
374
|
-
? this
|
|
269
|
+
? this.tabVmList.find(tab => tab.name === oldName)
|
|
375
270
|
: null,
|
|
376
271
|
newTab = newName !== void 0 && newName !== null && newName !== ''
|
|
377
|
-
? this
|
|
272
|
+
? this.tabVmList.find(tab => tab.name === newName)
|
|
378
273
|
: null
|
|
379
274
|
|
|
380
275
|
if (oldTab && newTab) {
|
|
381
276
|
const
|
|
382
|
-
oldEl = oldTab.$
|
|
383
|
-
newEl = newTab.$
|
|
277
|
+
oldEl = oldTab.$refs.tabIndicator,
|
|
278
|
+
newEl = newTab.$refs.tabIndicator
|
|
384
279
|
|
|
385
280
|
clearTimeout(this.animateTimer)
|
|
386
281
|
|
|
@@ -398,7 +293,7 @@ export default Vue.extend({
|
|
|
398
293
|
: `translate3d(${oldPos.left - newPos.left}px,0,0) scale3d(${newPos.width ? oldPos.width / newPos.width : 1},1,1)`
|
|
399
294
|
|
|
400
295
|
// allow scope updates to kick in (QRouteTab needs more time)
|
|
401
|
-
this
|
|
296
|
+
this.__registerAnimateTick(() => {
|
|
402
297
|
this.animateTimer = setTimeout(() => {
|
|
403
298
|
newEl.style.transition = 'transform .25s cubic-bezier(.4, 0, .2, 1)'
|
|
404
299
|
newEl.style.transform = 'none'
|
|
@@ -407,72 +302,129 @@ export default Vue.extend({
|
|
|
407
302
|
}
|
|
408
303
|
|
|
409
304
|
if (newTab && this.scrollable === true) {
|
|
410
|
-
this.
|
|
305
|
+
this.__scrollToTabEl(newTab.$el)
|
|
411
306
|
}
|
|
412
|
-
|
|
413
|
-
|
|
307
|
+
},
|
|
308
|
+
|
|
309
|
+
__scrollToTabEl (el) {
|
|
310
|
+
const
|
|
311
|
+
contentRef = this.$refs.content,
|
|
312
|
+
{ left, width, top, height } = contentRef.getBoundingClientRect(),
|
|
313
|
+
newPos = el.getBoundingClientRect()
|
|
314
|
+
|
|
315
|
+
let offset = this.vertical === true ? newPos.top - top : newPos.left - left
|
|
316
|
+
|
|
317
|
+
if (offset < 0) {
|
|
318
|
+
contentRef[ this.vertical === true ? 'scrollTop' : 'scrollLeft' ] += Math.floor(offset)
|
|
319
|
+
this.__localUpdateArrows()
|
|
320
|
+
return
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
offset += this.vertical === true ? newPos.height - height : newPos.width - width
|
|
324
|
+
if (offset > 0) {
|
|
325
|
+
contentRef[ this.vertical === true ? 'scrollTop' : 'scrollLeft' ] += Math.ceil(offset)
|
|
326
|
+
this.__localUpdateArrows()
|
|
414
327
|
}
|
|
415
328
|
},
|
|
416
329
|
|
|
417
330
|
__updateArrowsFn () {
|
|
418
|
-
const
|
|
419
|
-
|
|
420
|
-
if (content !== void 0) {
|
|
331
|
+
const content = this.$refs.content
|
|
332
|
+
if (content !== null) {
|
|
421
333
|
const
|
|
422
334
|
rect = content.getBoundingClientRect(),
|
|
423
|
-
pos = this.
|
|
335
|
+
pos = this.vertical === true ? content.scrollTop : Math.abs(content.scrollLeft)
|
|
424
336
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
337
|
+
if (this.isRTL === true) {
|
|
338
|
+
this.leftArrow = Math.ceil(pos + rect.width) < content.scrollWidth - 1
|
|
339
|
+
this.rightArrow = pos > 0
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
this.leftArrow = pos > 0
|
|
343
|
+
this.rightArrow = this.vertical === true
|
|
344
|
+
? Math.ceil(pos + rect.height) < content.scrollHeight
|
|
345
|
+
: Math.ceil(pos + rect.width) < content.scrollWidth
|
|
346
|
+
}
|
|
429
347
|
}
|
|
430
348
|
},
|
|
431
349
|
|
|
432
|
-
__animScrollTo (value
|
|
350
|
+
__animScrollTo (value) {
|
|
433
351
|
this.__stopAnimScroll()
|
|
434
|
-
|
|
435
|
-
this.__onAnimScrollEnd = onEnd
|
|
436
|
-
this.__scrollTowards(value)
|
|
437
|
-
|
|
438
352
|
this.scrollTimer = setInterval(() => {
|
|
439
|
-
if (this.__scrollTowards(value)) {
|
|
353
|
+
if (this.__scrollTowards(value) === true) {
|
|
440
354
|
this.__stopAnimScroll()
|
|
441
355
|
}
|
|
442
356
|
}, 5)
|
|
443
357
|
},
|
|
444
358
|
|
|
445
359
|
__scrollToStart () {
|
|
446
|
-
this.__animScrollTo(0)
|
|
360
|
+
this.__animScrollTo(this.rtlPosCorrection === true ? Number.MAX_SAFE_INTEGER : 0)
|
|
447
361
|
},
|
|
448
362
|
|
|
449
363
|
__scrollToEnd () {
|
|
450
|
-
this.__animScrollTo(Number.MAX_SAFE_INTEGER)
|
|
364
|
+
this.__animScrollTo(this.rtlPosCorrection === true ? 0 : Number.MAX_SAFE_INTEGER)
|
|
451
365
|
},
|
|
452
366
|
|
|
453
367
|
__stopAnimScroll () {
|
|
454
368
|
clearInterval(this.scrollTimer)
|
|
369
|
+
},
|
|
455
370
|
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
371
|
+
// used by children
|
|
372
|
+
__onKbdNavigate (keyCode, fromEl) {
|
|
373
|
+
const tabs = Array.prototype.filter.call(
|
|
374
|
+
this.$refs.content.children,
|
|
375
|
+
el => el === fromEl || (el.matches && el.matches('.q-tab.q-focusable') === true)
|
|
376
|
+
)
|
|
377
|
+
|
|
378
|
+
const len = tabs.length
|
|
379
|
+
if (len === 0) { return }
|
|
380
|
+
|
|
381
|
+
if (keyCode === 36) { // Home
|
|
382
|
+
this.__scrollToTabEl(tabs[ 0 ])
|
|
383
|
+
tabs[ 0 ].focus()
|
|
384
|
+
return true
|
|
385
|
+
}
|
|
386
|
+
if (keyCode === 35) { // End
|
|
387
|
+
this.__scrollToTabEl(tabs[ len - 1 ])
|
|
388
|
+
tabs[ len - 1 ].focus()
|
|
389
|
+
return true
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
const dirPrev = keyCode === (this.vertical === true ? 38 /* ArrowUp */ : 37 /* ArrowLeft */)
|
|
393
|
+
const dirNext = keyCode === (this.vertical === true ? 40 /* ArrowDown */ : 39 /* ArrowRight */)
|
|
394
|
+
|
|
395
|
+
const dir = dirPrev === true ? -1 : (dirNext === true ? 1 : void 0)
|
|
396
|
+
|
|
397
|
+
if (dir !== void 0) {
|
|
398
|
+
const rtlDir = this.isRTL === true ? -1 : 1
|
|
399
|
+
const index = tabs.indexOf(fromEl) + dir * rtlDir
|
|
400
|
+
|
|
401
|
+
if (index >= 0 && index < len) {
|
|
402
|
+
this.__scrollToTabEl(tabs[ index ])
|
|
403
|
+
tabs[ index ].focus({ preventScroll: true })
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
return true
|
|
459
407
|
}
|
|
460
408
|
},
|
|
461
409
|
|
|
462
410
|
__scrollTowards (value) {
|
|
463
|
-
const
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
let pos = this.__getScrollPosition(content)
|
|
467
|
-
let done = false
|
|
411
|
+
const
|
|
412
|
+
content = this.$refs.content,
|
|
413
|
+
{ get, set } = this.posFn
|
|
468
414
|
|
|
469
|
-
|
|
415
|
+
let
|
|
416
|
+
done = false,
|
|
417
|
+
pos = get(content)
|
|
470
418
|
|
|
471
419
|
const direction = value < pos ? -1 : 1
|
|
472
420
|
|
|
473
421
|
pos += direction * 5
|
|
474
422
|
|
|
475
|
-
if (
|
|
423
|
+
if (pos < 0) {
|
|
424
|
+
done = true
|
|
425
|
+
pos = 0
|
|
426
|
+
}
|
|
427
|
+
else if (
|
|
476
428
|
(direction === -1 && pos <= value) ||
|
|
477
429
|
(direction === 1 && pos >= value)
|
|
478
430
|
) {
|
|
@@ -480,140 +432,272 @@ export default Vue.extend({
|
|
|
480
432
|
pos = value
|
|
481
433
|
}
|
|
482
434
|
|
|
483
|
-
|
|
484
|
-
this.
|
|
435
|
+
set(content, pos)
|
|
436
|
+
this.__localUpdateArrows()
|
|
485
437
|
|
|
486
438
|
return done
|
|
487
439
|
},
|
|
488
440
|
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
}
|
|
441
|
+
// do not use directly; use __verifyRouteModel() instead
|
|
442
|
+
__updateActiveRoute () {
|
|
443
|
+
let name = null, bestScore = getDefaultBestScore()
|
|
493
444
|
|
|
494
|
-
const
|
|
495
|
-
const
|
|
496
|
-
const sizeContent = this.vertical === true ? content.offsetHeight : content.offsetWidth
|
|
497
|
-
const sizeScroll = this.vertical === true ? content.scrollHeight : content.scrollWidth
|
|
445
|
+
const vmList = this.tabVmList.filter(tab => tab.hasRouterLink === true)
|
|
446
|
+
const vmLen = vmList.length
|
|
498
447
|
|
|
499
|
-
const
|
|
500
|
-
const
|
|
448
|
+
const { query: currentQuery } = this.$route
|
|
449
|
+
const currentQueryLen = Object.keys(currentQuery).length
|
|
501
450
|
|
|
502
|
-
|
|
503
|
-
|
|
451
|
+
for (let tabIndex = 0; tabIndex < vmLen; tabIndex++) {
|
|
452
|
+
const tab = vmList[tabIndex]
|
|
453
|
+
const exact = tab.exact === true
|
|
504
454
|
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
455
|
+
// if a) it doesn't respect the active/exact active status
|
|
456
|
+
// or b) we already found an exact match and this one isn't set as exact
|
|
457
|
+
// then we don't deal with it
|
|
458
|
+
if (
|
|
459
|
+
tab[ exact === true ? 'linkIsExactActive' : 'linkIsActive' ] !== true ||
|
|
460
|
+
(bestScore.exact === true && exact !== true)
|
|
461
|
+
) {
|
|
462
|
+
continue
|
|
511
463
|
}
|
|
512
|
-
|
|
513
|
-
|
|
464
|
+
|
|
465
|
+
const { route, href } = tab.resolvedLink
|
|
466
|
+
const { matched, query, hash } = route
|
|
467
|
+
const redirected = route.redirectedFrom !== void 0
|
|
468
|
+
|
|
469
|
+
if (exact === true) {
|
|
470
|
+
// hey, we found the perfect match; no more searching!
|
|
471
|
+
if (redirected === false) {
|
|
472
|
+
name = tab.name
|
|
473
|
+
break
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
if (bestScore.exact === false) {
|
|
477
|
+
// we reset values so we can discard previous non-exact matches
|
|
478
|
+
// and so we can register this exact one below
|
|
479
|
+
bestScore = getDefaultBestScore()
|
|
480
|
+
}
|
|
514
481
|
}
|
|
515
|
-
|
|
516
|
-
|
|
482
|
+
|
|
483
|
+
// if best is non-redirected and this one is redirected
|
|
484
|
+
// then this one is inferior so we don't care about it
|
|
485
|
+
if (bestScore.redirected === false && redirected === true) {
|
|
486
|
+
continue
|
|
517
487
|
}
|
|
518
|
-
}
|
|
519
488
|
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
489
|
+
const queryLen = Object.keys(query).length
|
|
490
|
+
|
|
491
|
+
if (
|
|
492
|
+
// if it's exact it already perfectly includes current query
|
|
493
|
+
// so no point in computing it
|
|
494
|
+
exact === false &&
|
|
495
|
+
queryLen !== 0 &&
|
|
496
|
+
hasQueryIncluded(query, currentQuery) === false
|
|
497
|
+
) {
|
|
498
|
+
// it has query and it doesn't includes the current one
|
|
499
|
+
continue
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
const newScore = {
|
|
503
|
+
exact,
|
|
504
|
+
redirected,
|
|
505
|
+
matchedLen: matched.length,
|
|
506
|
+
queryDiff: exact === true
|
|
507
|
+
? 0 // avoid computing as it's 0 anyway
|
|
508
|
+
: currentQueryLen - queryLen,
|
|
509
|
+
hrefLen: href.length - hash.length
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
if (newScore.matchedLen > bestScore.matchedLen) {
|
|
513
|
+
// it matches more routes so it's more specific so we set it as current champion
|
|
514
|
+
name = tab.name
|
|
515
|
+
bestScore = newScore
|
|
516
|
+
continue
|
|
517
|
+
}
|
|
518
|
+
else if (newScore.matchedLen !== bestScore.matchedLen) {
|
|
519
|
+
// it matches less routes than the current champion so we discard it
|
|
520
|
+
continue
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
if (newScore.queryDiff < bestScore.queryDiff) {
|
|
524
|
+
// query is closer to the current one so we set it as current champion
|
|
525
|
+
name = tab.name
|
|
526
|
+
bestScore = newScore
|
|
527
|
+
continue
|
|
528
|
+
}
|
|
529
|
+
else if (newScore.queryDiff !== bestScore.queryDiff) {
|
|
530
|
+
continue
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
if (newScore.hrefLen > bestScore.hrefLen) {
|
|
534
|
+
// href is lengthier so it's more specific so we set it as current champion
|
|
535
|
+
name = tab.name
|
|
536
|
+
bestScore = newScore
|
|
537
|
+
}
|
|
531
538
|
}
|
|
532
|
-
|
|
533
|
-
|
|
539
|
+
|
|
540
|
+
if (
|
|
541
|
+
name === null &&
|
|
542
|
+
this.tabVmList.some(tab => tab.hasRouterLink === void 0 && tab.name === this.currentModel) === true
|
|
543
|
+
) {
|
|
544
|
+
// we shouldn't interfere if non-route tab is active
|
|
545
|
+
return
|
|
534
546
|
}
|
|
547
|
+
|
|
548
|
+
this.__updateModel({ name, setCurrent: true })
|
|
535
549
|
},
|
|
536
550
|
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
const tabs = Array.prototype.filter.call(this.$refs.content.children, matchTab)
|
|
540
|
-
const tabsLength = tabs.length
|
|
551
|
+
__onFocusin (e) {
|
|
552
|
+
this.__removeFocusTimeout()
|
|
541
553
|
|
|
542
|
-
if (
|
|
543
|
-
|
|
544
|
-
|
|
554
|
+
if (
|
|
555
|
+
this.hasFocus !== true &&
|
|
556
|
+
this.$el &&
|
|
557
|
+
e.target &&
|
|
558
|
+
typeof e.target.closest === 'function'
|
|
559
|
+
) {
|
|
560
|
+
const tab = e.target.closest('.q-tab')
|
|
545
561
|
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
562
|
+
// if the target is contained by a QTab/QRouteTab
|
|
563
|
+
// (it might be other elements focused, like additional QBtn)
|
|
564
|
+
if (tab && this.$el.contains(tab) === true) {
|
|
565
|
+
this.hasFocus = true
|
|
566
|
+
|
|
567
|
+
if (this.scrollable === true) {
|
|
568
|
+
this.__scrollToTabEl(tab)
|
|
569
|
+
}
|
|
549
570
|
}
|
|
571
|
+
}
|
|
550
572
|
|
|
551
|
-
|
|
552
|
-
|
|
573
|
+
this.qListeners.focusin !== void 0 && this.$emit('focusin', e)
|
|
574
|
+
},
|
|
553
575
|
|
|
554
|
-
|
|
576
|
+
__onFocusout (e) {
|
|
577
|
+
this.__registerFocusTimeout(() => { this.hasFocus = false }, 30)
|
|
578
|
+
this.qListeners.focusout !== void 0 && this.$emit('focusout', e)
|
|
579
|
+
},
|
|
580
|
+
|
|
581
|
+
// used by children
|
|
582
|
+
__verifyRouteModel () {
|
|
583
|
+
if (this.avoidRouteWatcher === false) {
|
|
584
|
+
this.__registerScrollToTabTimeout(this.__updateActiveRoute)
|
|
555
585
|
}
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
586
|
+
else {
|
|
587
|
+
this.__removeScrollToTabTimeout()
|
|
588
|
+
}
|
|
589
|
+
},
|
|
590
|
+
|
|
591
|
+
__watchRoute () {
|
|
592
|
+
if (this.unwatchRoute === void 0) {
|
|
593
|
+
const unwatch = this.$watch(() => this.$route.fullPath, this.__verifyRouteModel)
|
|
594
|
+
this.unwatchRoute = () => {
|
|
595
|
+
unwatch()
|
|
596
|
+
this.unwatchRoute = void 0
|
|
559
597
|
}
|
|
598
|
+
}
|
|
599
|
+
},
|
|
560
600
|
|
|
561
|
-
|
|
562
|
-
|
|
601
|
+
// used by children
|
|
602
|
+
__registerTab (tabVm) {
|
|
603
|
+
// we avoid setting tabVmList in data() as this would
|
|
604
|
+
// make the whole vm reactive
|
|
605
|
+
this.tabVmList.push(tabVm)
|
|
606
|
+
// ...so we extract only the needed stuff out of it
|
|
607
|
+
// into data() defined tabNameList
|
|
608
|
+
this.tabNameList.push(
|
|
609
|
+
injectProp({}, 'name', () => tabVm.name)
|
|
610
|
+
)
|
|
563
611
|
|
|
564
|
-
|
|
612
|
+
this.__recalculateScroll()
|
|
613
|
+
|
|
614
|
+
// if it's a QTab
|
|
615
|
+
if (tabVm.hasRouterLink === void 0) {
|
|
616
|
+
// we should position to the currently active tab (if any)
|
|
617
|
+
this.__registerScrollToTabTimeout(() => {
|
|
618
|
+
if (this.scrollable === true) {
|
|
619
|
+
const value = this.currentModel
|
|
620
|
+
const newTab = value !== void 0 && value !== null && value !== ''
|
|
621
|
+
? this.tabVmList.find(tab => tab.name === value)
|
|
622
|
+
: null
|
|
623
|
+
|
|
624
|
+
newTab && this.__scrollToTabEl(newTab.$el)
|
|
625
|
+
}
|
|
626
|
+
})
|
|
565
627
|
}
|
|
628
|
+
// else if it's a QRouteTab with a valid link
|
|
629
|
+
else {
|
|
630
|
+
this.__watchRoute()
|
|
566
631
|
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
632
|
+
if (tabVm.hasRouterLink === true) {
|
|
633
|
+
this.__verifyRouteModel()
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
},
|
|
572
637
|
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
638
|
+
/*
|
|
639
|
+
* Vue has an aggressive diff (in-place replacement) so we cannot
|
|
640
|
+
* ensure that the instance getting destroyed is the actual tab
|
|
641
|
+
* reported here. As a result, we cannot use its name or check
|
|
642
|
+
* if it's a route one to make the necessary updates. We need to
|
|
643
|
+
* always check the existing list again and infer the changes.
|
|
644
|
+
*/
|
|
645
|
+
// used by children
|
|
646
|
+
__unregisterTab (tabVm) {
|
|
647
|
+
const index = this.tabVmList.indexOf(tabVm)
|
|
576
648
|
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
index >= tabsLength ||
|
|
580
|
-
tabs[index].contains(document.activeElement) === true
|
|
581
|
-
) {
|
|
582
|
-
return false
|
|
583
|
-
}
|
|
649
|
+
this.tabVmList.splice(index, 1)
|
|
650
|
+
this.tabNameList.splice(index, 1)
|
|
584
651
|
|
|
585
|
-
|
|
586
|
-
this.__recalculateScroll()
|
|
652
|
+
this.__recalculateScroll()
|
|
587
653
|
|
|
588
|
-
|
|
654
|
+
// if we're watching route and this tab is a QRouteTab
|
|
655
|
+
if (this.unwatchRoute !== void 0 && tabVm.hasRouterLink !== void 0) {
|
|
656
|
+
// unwatch route if we don't have any QRouteTabs left
|
|
657
|
+
if (this.tabVmList.every(tab => tab.hasRouterLink === void 0) === true) {
|
|
658
|
+
this.unwatchRoute()
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
// then update model
|
|
662
|
+
this.__verifyRouteModel()
|
|
589
663
|
}
|
|
664
|
+
},
|
|
665
|
+
|
|
666
|
+
__cleanup () {
|
|
667
|
+
clearTimeout(this.animateTimer)
|
|
668
|
+
this.__stopAnimScroll()
|
|
669
|
+
this.unwatchRoute !== void 0 && this.unwatchRoute()
|
|
590
670
|
}
|
|
591
671
|
},
|
|
592
672
|
|
|
593
673
|
created () {
|
|
594
|
-
this.
|
|
674
|
+
this.__useTick('__registerScrollTick')
|
|
675
|
+
this.__useTick('__registerUpdateArrowsTick')
|
|
676
|
+
this.__useTick('__registerAnimateTick')
|
|
595
677
|
|
|
596
|
-
this.
|
|
597
|
-
|
|
598
|
-
: noop
|
|
599
|
-
},
|
|
678
|
+
this.__useTimeout('__registerFocusTimeout', '__removeFocusTimeout')
|
|
679
|
+
this.__useTimeout('__registerScrollToTabTimeout', '__removeScrollToTabTimeout')
|
|
600
680
|
|
|
601
|
-
|
|
602
|
-
|
|
681
|
+
Object.assign(this, {
|
|
682
|
+
tabVmList: [],
|
|
683
|
+
__localUpdateArrows: this.arrowsEnabled === true
|
|
684
|
+
? this.__updateArrowsFn
|
|
685
|
+
: noop
|
|
686
|
+
})
|
|
603
687
|
},
|
|
604
688
|
|
|
605
689
|
activated () {
|
|
606
|
-
|
|
690
|
+
this.hadRouteWatcher === true && this.__watchRoute()
|
|
607
691
|
this.__recalculateScroll()
|
|
608
692
|
},
|
|
609
693
|
|
|
610
694
|
deactivated () {
|
|
611
|
-
this.
|
|
695
|
+
this.hadRouteWatcher = this.unwatchRoute !== void 0
|
|
696
|
+
this.__cleanup()
|
|
612
697
|
},
|
|
613
698
|
|
|
614
699
|
beforeDestroy () {
|
|
615
|
-
|
|
616
|
-
clearTimeout(this.animateTimer)
|
|
700
|
+
this.__cleanup()
|
|
617
701
|
},
|
|
618
702
|
|
|
619
703
|
render (h) {
|
|
@@ -624,7 +708,6 @@ export default Vue.extend({
|
|
|
624
708
|
|
|
625
709
|
h('div', {
|
|
626
710
|
ref: 'content',
|
|
627
|
-
staticClass: 'q-tabs__content row no-wrap items-center self-stretch hide-scrollbar relative-position',
|
|
628
711
|
class: this.innerClass,
|
|
629
712
|
on: this.arrowsEnabled === true ? cache(this, 'scroll', { scroll: this.__updateArrowsFn }) : void 0
|
|
630
713
|
}, slot(this, 'default'))
|
|
@@ -632,34 +715,33 @@ export default Vue.extend({
|
|
|
632
715
|
|
|
633
716
|
this.arrowsEnabled === true && child.push(
|
|
634
717
|
h(QIcon, {
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
props: { name: this.
|
|
718
|
+
class: 'q-tabs__arrow q-tabs__arrow--start absolute q-tab__icon' +
|
|
719
|
+
(this.leftArrow === true ? '' : ' q-tabs__arrow--faded'),
|
|
720
|
+
props: { name: this.leftIcon || this.$q.iconSet.tabs[ this.vertical === true ? 'up' : 'left' ] },
|
|
638
721
|
on: cache(this, 'onS', {
|
|
639
|
-
mousedown: this.__scrollToStart,
|
|
640
|
-
touchstart: this.__scrollToStart,
|
|
641
|
-
mouseup: this.__stopAnimScroll,
|
|
642
|
-
mouseleave: this.__stopAnimScroll,
|
|
643
|
-
touchend: this.__stopAnimScroll
|
|
722
|
+
'&mousedown': this.__scrollToStart,
|
|
723
|
+
'&touchstart': this.__scrollToStart,
|
|
724
|
+
'&mouseup': this.__stopAnimScroll,
|
|
725
|
+
'&mouseleave': this.__stopAnimScroll,
|
|
726
|
+
'&touchend': this.__stopAnimScroll
|
|
644
727
|
})
|
|
645
728
|
}),
|
|
646
729
|
|
|
647
730
|
h(QIcon, {
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
props: { name: this.
|
|
731
|
+
class: 'q-tabs__arrow q-tabs__arrow--end absolute q-tab__icon' +
|
|
732
|
+
(this.rightArrow === true ? '' : ' q-tabs__arrow--faded'),
|
|
733
|
+
props: { name: this.rightIcon || this.$q.iconSet.tabs[ this.vertical === true ? 'down' : 'right' ] },
|
|
651
734
|
on: cache(this, 'onE', {
|
|
652
|
-
mousedown: this.__scrollToEnd,
|
|
653
|
-
touchstart: this.__scrollToEnd,
|
|
654
|
-
mouseup: this.__stopAnimScroll,
|
|
655
|
-
mouseleave: this.__stopAnimScroll,
|
|
656
|
-
touchend: this.__stopAnimScroll
|
|
735
|
+
'&mousedown': this.__scrollToEnd,
|
|
736
|
+
'&touchstart': this.__scrollToEnd,
|
|
737
|
+
'&mouseup': this.__stopAnimScroll,
|
|
738
|
+
'&mouseleave': this.__stopAnimScroll,
|
|
739
|
+
'&touchend': this.__stopAnimScroll
|
|
657
740
|
})
|
|
658
741
|
})
|
|
659
742
|
)
|
|
660
743
|
|
|
661
744
|
return h('div', {
|
|
662
|
-
staticClass: 'q-tabs row no-wrap items-center',
|
|
663
745
|
class: this.classes,
|
|
664
746
|
on: this.onEvents,
|
|
665
747
|
attrs: { role: 'tablist' }
|