<a class='main-nav-link {selected ? "selected" : ""}' aria-label={ariaLabel} aria-current={selected} on:click="onClick(event)" {href} > <div class="nav-icon-and-label"> {#if name === 'notifications'} <div class="nav-link-svg-wrapper"> <svg class="nav-link-svg"> <use xlink:href={svg} /> </svg> {#if $hasNotifications} <span class="nav-link-notifications nav-link-notifications-digits-{notificationDigits}" aria-hidden="true"> {$numberOfNotifications} </span> {/if} </div> {:else} <svg class="nav-link-svg"> <use xlink:href={svg} /> </svg> {/if} <span class="nav-link-label">{label}</span> </div> <div class="nav-indicator" nav-indicator-key={name} ref:indicator ></div> </a> <style> .main-nav-link { text-decoration: none; display: flex; justify-content: center; align-items: center; flex: 1; flex-direction: column; } .nav-icon-and-label { padding: 15px 20px; display: flex; justify-content: center; align-items: center; flex: 1; } .nav-link-svg-wrapper { position: relative; display: inline-block; } .nav-link-svg-wrapper, .nav-link-svg { width: 20px; height: 20px; } .nav-link-notifications { position: absolute; display: flex; align-items: center; justify-content: center; top: 0; right: 0; bottom: 0; left: 0; transform: translate(10px, 7px); z-index: 10; border: 1px solid var(--nav-bg); background: var(--nav-svg-fill); color: var(--nav-bg); border-radius: 100%; font-size: 0.8em; margin: 0 0 3px; font-weight: 600; } .nav-link-notifications-digits-2, .nav-link-notifications-digits-3 { font-size: 0.7em; } .main-nav-link.selected { background: var(--nav-a-selected-bg); } .main-nav-link.selected:hover { background: var(--nav-a-selected-bg-hover); } .nav-indicator { width: 100%; height: 1px; background: var(--nav-a-border); transform-origin: left; } .nav-indicator.animate { transition: transform 333ms ease-in-out; } .main-nav-link:hover .nav-indicator { background: var(--nav-a-border-hover); } .main-nav-link.selected .nav-indicator { background: var(--nav-a-selected-border); } .main-nav-link.selected:hover .nav-indicator { background: var(--nav-a-selected-border-hover); } .main-nav-link:hover { background-color: var(--nav-a-bg-hover); text-decoration: none; } .main-nav-link:hover .nav-link-label { color: var(--nav-text-color-hover); } .main-nav-link:hover .nav-link-svg { fill: var(--nav-svg-fill-hover); } .nav-link-svg { display: inline-block; fill: var(--nav-svg-fill); } .nav-link-label { font-size: 16px; color: var(--nav-text-color); padding-left: 10px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } @media (max-width: 991px) { .main-nav-link .nav-link-label { display: none; } .nav-link-svg-wrapper, .nav-link-svg { width: 25px; height: 25px; } .nav-icon-and-label { padding: 20px 0; } .nav-link-notifications { transform: translate(15px, 7px); margin: 2px 1px 4px; } } </style> <script> import { store } from '../_store/store' import { smoothScrollToTop } from '../_utils/smoothScrollToTop' import { on, emit } from '../_utils/eventBus' import { mark, stop } from '../_utils/marks' import { doubleRAF } from '../_utils/doubleRAF' import { getScrollContainer } from '../_utils/scrollContainer' export default { oncreate () { let { name } = this.get() let indicator = this.refs.indicator on('animateNavPart1', this, ({ fromPage, toPage }) => { if (fromPage !== name) { return } mark('animateNavPart1 gBCR') let fromRect = indicator.getBoundingClientRect() stop('animateNavPart1 gBCR') emit('animateNavPart2', { fromRect, fromPage, toPage }) }) on('animateNavPart2', this, ({ fromPage, fromRect, toPage }) => { if (toPage !== name) { return } mark('animateNavPart2 gBCR') let toRect = indicator.getBoundingClientRect() stop('animateNavPart2 gBCR') let translateX = fromRect.left - toRect.left let scaleX = fromRect.width / toRect.width indicator.style.transform = `translateX(${translateX}px) scaleX(${scaleX})` let onTransitionEnd = () => { indicator.removeEventListener('transitionend', onTransitionEnd) indicator.classList.remove('animate') } indicator.addEventListener('transitionend', onTransitionEnd) doubleRAF(() => { indicator.classList.add('animate') indicator.style.transform = '' }) }) }, store: () => store, computed: { selected: ({ page, name }) => page === name, ariaLabel: ({ selected, name, label, $numberOfNotifications }) => { let res = label if (selected) { res += ' (current page)' } if (name === 'notifications' && $numberOfNotifications) { res += ` (${$numberOfNotifications})` } return res }, notificationDigits: ({ $numberOfNotifications }) => ( $numberOfNotifications.toString().length ) }, methods: { onClick (e) { let { selected } = this.get() if (!selected) { return } e.preventDefault() e.stopPropagation() smoothScrollToTop(getScrollContainer()) } } } </script>