diff options
Diffstat (limited to 'app/assets/javascripts/super_sidebar')
5 files changed, 89 insertions, 8 deletions
diff --git a/app/assets/javascripts/super_sidebar/components/nav_item.vue b/app/assets/javascripts/super_sidebar/components/nav_item.vue index 9dc26ad10f5..8382ae8987b 100644 --- a/app/assets/javascripts/super_sidebar/components/nav_item.vue +++ b/app/assets/javascripts/super_sidebar/components/nav_item.vue @@ -7,6 +7,8 @@ import { TRACKING_UNKNOWN_ID, TRACKING_UNKNOWN_PANEL, } from '~/super_sidebar/constants'; +import NavItemLink from './nav_item_link.vue'; +import NavItemRouterLink from './nav_item_router_link.vue'; export default { i18n: { @@ -18,6 +20,8 @@ export default { GlButton, GlIcon, GlBadge, + NavItemLink, + NavItemRouterLink, }, inject: { pinnedItemIds: { default: { ids: [] } }, @@ -55,9 +59,6 @@ export default { (typeof this.pillData === 'string' && this.pillData !== '') ); }, - isActive() { - return this.item.is_active; - }, isPinnable() { return this.panelSupportsPins && !this.isStatic; }, @@ -86,27 +87,30 @@ export default { return { ...this.$attrs, ...this.trackingProps, - href: this.item.link, - 'aria-current': this.isActive ? 'page' : null, + item: this.item, 'data-qa-submenu-item': this.item.title, }; }, computedLinkClasses() { return { - 'gl-bg-t-gray-a-08': this.isActive, 'gl-py-2': this.isPinnable, 'gl-py-3': !this.isPinnable, [this.item.link_classes]: this.item.link_classes, ...this.linkClasses, }; }, + navItemLinkComponent() { + return this.item.to ? NavItemRouterLink : NavItemLink; + }, }, }; </script> <template> <li> - <a + <component + :is="navItemLinkComponent" + #default="{ isActive }" v-bind="linkProps" class="nav-item-link gl-rounded-base gl-relative gl-display-flex gl-align-items-center gl-mb-1 gl-px-0 gl-line-height-normal gl-text-black-normal! gl-hover-bg-t-gray-a-08 gl-focus-bg-t-gray-a-08 gl-text-decoration-none! gl-focus--focus" :class="computedLinkClasses" @@ -118,6 +122,7 @@ export default { class="gl-absolute gl-left-2 gl-top-2 gl-bottom-2 gl-transition-slow" aria-hidden="true" style="width: 3px; border-radius: 3px; margin-right: 1px" + data-testid="active-indicator" ></div> <div class="gl-flex-shrink-0 gl-w-6 gl-mx-3"> <slot name="icon"> @@ -162,6 +167,6 @@ export default { @click.prevent="$emit('pin-remove', item.id)" /> </span> - </a> + </component> </li> </template> diff --git a/app/assets/javascripts/super_sidebar/components/nav_item_link.vue b/app/assets/javascripts/super_sidebar/components/nav_item_link.vue new file mode 100644 index 00000000000..8358e96db94 --- /dev/null +++ b/app/assets/javascripts/super_sidebar/components/nav_item_link.vue @@ -0,0 +1,35 @@ +<script> +import { NAV_ITEM_LINK_ACTIVE_CLASS } from '../constants'; +import { ariaCurrent } from '../utils'; + +export default { + props: { + item: { + type: Object, + required: true, + }, + }, + computed: { + isActive() { + return this.item.is_active; + }, + linkProps() { + return { + href: this.item.link, + 'aria-current': ariaCurrent(this.isActive), + }; + }, + computedLinkClasses() { + return { + [NAV_ITEM_LINK_ACTIVE_CLASS]: this.isActive, + }; + }, + }, +}; +</script> + +<template> + <a v-bind="linkProps" :class="computedLinkClasses"> + <slot :is-active="isActive"></slot> + </a> +</template> diff --git a/app/assets/javascripts/super_sidebar/components/nav_item_router_link.vue b/app/assets/javascripts/super_sidebar/components/nav_item_router_link.vue new file mode 100644 index 00000000000..78aca24d9a6 --- /dev/null +++ b/app/assets/javascripts/super_sidebar/components/nav_item_router_link.vue @@ -0,0 +1,37 @@ +<script> +import { NAV_ITEM_LINK_ACTIVE_CLASS } from '../constants'; +import { ariaCurrent } from '../utils'; + +export default { + NAV_ITEM_LINK_ACTIVE_CLASS, + props: { + item: { + type: Object, + required: true, + }, + }, + computed: { + linkProps() { + return { + to: this.item.to, + }; + }, + }, + methods: { + ariaCurrent, + }, +}; +</script> + +<template> + <router-link + #default="{ href, navigate, isActive }" + v-bind="linkProps" + :active-class="$options.NAV_ITEM_LINK_ACTIVE_CLASS" + custom + > + <a :href="href" :aria-current="ariaCurrent(isActive)" @click="navigate"> + <slot :is-active="isActive"></slot> + </a> + </router-link> +</template> diff --git a/app/assets/javascripts/super_sidebar/constants.js b/app/assets/javascripts/super_sidebar/constants.js index 4a5d0bf637f..00ceaebe2cc 100644 --- a/app/assets/javascripts/super_sidebar/constants.js +++ b/app/assets/javascripts/super_sidebar/constants.js @@ -50,3 +50,5 @@ export const SIDEBAR_PINS_EXPANDED_COOKIE = 'sidebar_pinned_section_expanded'; export const SIDEBAR_COOKIE_EXPIRATION = 365 * 10; export const DROPDOWN_Y_OFFSET = 4; + +export const NAV_ITEM_LINK_ACTIVE_CLASS = 'gl-bg-t-gray-a-08'; diff --git a/app/assets/javascripts/super_sidebar/utils.js b/app/assets/javascripts/super_sidebar/utils.js index 4bbef67742c..3b17a35c5bc 100644 --- a/app/assets/javascripts/super_sidebar/utils.js +++ b/app/assets/javascripts/super_sidebar/utils.js @@ -83,3 +83,5 @@ export const formatContextSwitcherItems = (items) => avatar, link, })); + +export const ariaCurrent = (isActive) => (isActive ? 'page' : null); |