Skip to content

Commit

Permalink
feat(QTabs): tweak updateActiveRoute + improve tabs-router example
Browse files Browse the repository at this point in the history
  • Loading branch information
rstoenescu committed Oct 1, 2022
1 parent 0c77106 commit 6603aa2
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 27 deletions.
33 changes: 21 additions & 12 deletions ui/dev/src/pages/components/tabs-router.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div class="q-pa-md">
<div class="q-gutter-y-md" style="max-width: 800px">
<div class="q-gutter-y-md">
<div class="row q-col-gutter-md justify-stretch">
<div class="col-12">Router-links</div>

Expand All @@ -18,23 +18,32 @@
</q-item>
</div>

<q-item class="special-router-link" replace :to="{ query: { tab: '3', noScroll: true, y: '5' } }" active-class="special-router-link--active" exact-active-class="special-router-link--exact-active">
<q-item-section>3 + y=5</q-item-section>
</q-item>

<div class="col-12">Route query {{ $route.query }}</div>

<div>
<q-item class="special-router-link" replace :to="{ query: { tab: '3', noScroll: true, y: '5' } }" active-class="special-router-link--active" exact-active-class="special-router-link--exact-active">
<q-item-section>3 + y=5 - select 3*</q-item-section>
</q-item>
</div>

<div>
<q-item class="special-router-link" replace :to="{ query: { tab: '3' } }" active-class="special-router-link--active" exact-active-class="special-router-link--exact-active">
<q-item-section>{ tab: 3 } - select none</q-item-section>
</q-item>
</div>
</div>

<q-tabs
no-caps
class="bg-orange text-white shadow-2"
>
<q-route-tab replace :to="{ query: { tab: '1', noScroll: true } }" label="[1] Activate in 2s" @click="navDelay" />
<q-route-tab replace :to="{ query: { tab: '2', noScroll: true } }" label="[2] Do nothing" @click="navCancel" />
<q-route-tab replace :to="{ query: { tab: '3', noScroll: true } }" label="[3] Navigate to the second tab" @click="navRedirect" />
<q-route-tab replace :to="{ query: { tab: '4', noScroll: true } }" label="[4] Navigate immediately" @click="navPass" />
<q-route-tab replace :to="{ query: { tab: '1', noScroll: true } }" label="[1*] Activate in 2s" @click="navDelay" />
<q-route-tab replace :to="{ query: { tab: '2', noScroll: true } }" label="[2*] Do nothing" @click="navCancel" />
<q-route-tab replace :to="{ query: { tab: '3', noScroll: true } }" label="[3*] Navigate to the second tab" @click="navRedirect" />
<q-route-tab replace :to="{ query: { tab: '3', noScroll: true } }" exact label="[3] exact" @click="navPass" />
<q-route-tab replace :to="{ query: { tab: '4', noScroll: true } }" label="[4*] Navigate immediately" @click="navPass" />

<q-route-tab replace :to="{ query: { tab: '5', noScroll: true } }" label="[5] With button" @click="navPass">
<q-route-tab replace :to="{ query: { tab: '5', noScroll: true } }" label="[5*] With button" @click="navPass">
<q-btn unelevated :label="`Click (${ clickCounter })`" @click.stop.prevent="onClick" />
</q-route-tab>
</q-tabs>
Expand Down Expand Up @@ -91,9 +100,9 @@ export default {
text-align: center
text-decoration: none
color: black
padding: 2px
padding: 12px
border: 1px solid black
width: 50px
min-width: 50px
&--active
background-color: #ee9
Expand Down
43 changes: 28 additions & 15 deletions ui/src/components/tabs/QTabs.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { slot } from '../../utils/private/slot.js'
import cache from '../../utils/private/cache.js'
import { rtlHasScrollBug } from '../../utils/scroll.js'
import { injectProp } from '../../utils/private/inject-obj-prop.js'
import { isDeepEqual } from '../../utils/is.js'

function getIndicatorClass (color, top, vertical) {
const pos = vertical === true
Expand All @@ -22,18 +21,16 @@ function getIndicatorClass (color, top, vertical) {
}

const alignValues = [ 'left', 'center', 'right', 'justify' ]
const getDefaultBestScore = () => ({ matchedLen: 0, queryScore: 0, hrefLen: 0, exact: false, redirected: true })

function getQueryScore (targetQuery, matchingQuery) {
let score = 0
const getDefaultBestScore = () => ({ matchedLen: 0, queryDiff: 9999, hrefLen: 0, exact: false, redirected: true })

function hasQueryIncluded (targetQuery, matchingQuery) {
for (const key in targetQuery) {
if (isDeepEqual(targetQuery[ key ], matchingQuery[ key ]) === true) {
score++
if (targetQuery[ key ] !== matchingQuery[ key ]) {
return false
}
}

return score
return true
}

export default Vue.extend({
Expand Down Expand Up @@ -448,9 +445,13 @@ export default Vue.extend({
// do not use directly; use __verifyRouteModel() instead
__updateActiveRoute () {
let name = null, bestScore = getDefaultBestScore()

const vmList = this.tabVmList.filter(tab => tab.hasRouterLink === true)
const vmLen = vmList.length

const { query: currentQuery } = this.$route
const currentQueryLen = Object.keys(currentQuery).length

for (let tabIndex = 0; tabIndex < vmLen; tabIndex++) {
const tab = vmList[tabIndex]
const exact = tab.exact === true
Expand All @@ -466,7 +467,7 @@ export default Vue.extend({
}

const { route, href } = tab.resolvedLink
const { hash, matched, query } = route
const { matched, query, hash } = route
const redirected = route.redirectedFrom !== void 0

if (exact === true) {
Expand All @@ -489,13 +490,26 @@ export default Vue.extend({
continue
}

const queryLen = Object.keys(query).length

if (
// if it's exact it already perfectly includes current query
// so no point in computing it
exact === false &&
queryLen !== 0 &&
hasQueryIncluded(query, currentQuery) === false
) {
// it has query and it doesn't includes the current one
continue
}

const newScore = {
exact,
redirected,
matchedLen: matched.length,
queryScore: exact === true
? 0 // avoid computing as it's maximum anyway
: getQueryScore(query, this.$route.query),
queryDiff: exact === true
? 0 // avoid computing as it's 0 anyway
: currentQueryLen - queryLen,
hrefLen: href.length - hash.length
}

Expand All @@ -510,14 +524,13 @@ export default Vue.extend({
continue
}

if (newScore.queryScore > bestScore.queryScore) {
if (newScore.queryDiff < bestScore.queryDiff) {
// query is closer to the current one so we set it as current champion
name = tab.name
bestScore = newScore
continue
}
else if (newScore.queryScore !== bestScore.queryScore) {
// query is farther away than current champion so we discard it
else if (newScore.queryDiff !== bestScore.queryDiff) {
continue
}

Expand Down

0 comments on commit 6603aa2

Please sign in to comment.