Skip to content

Commit 8133769

Browse files
committed
feat: add api navigation item
See: FE-155
1 parent f8e62b0 commit 8133769

File tree

4 files changed

+135
-131
lines changed

4 files changed

+135
-131
lines changed

frontend/assets/css/colors.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@
214214
--light-tag-color: var(--light-grey);
215215

216216
--megamenu-panel-color: var(--graphite);
217-
--megamenu-text-color: var(--grey);
217+
--megamenu-text-color: var(--light-grey);
218218
--megamenu-hover-color: var(--asphalt);
219219

220220
--list-background: var(--light-black);

frontend/assets/css/prime_megamenu.scss

Lines changed: 60 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
background: var(--container-background);
44
user-select: none;
55
z-index: 1; // without this, the menu keeps a very high z-index when it is open in mobile mode and then the window is enlarged (the change of mode closes the menu but does not reset its z-index, so the menu bar floats above the search bar)
6+
margin-right: -.75rem; // keep items' text right-aligned to page while showing consistent outline padding on focus
67

78
.p-megamenu-root-list:focus {
89
outline: none;
@@ -14,56 +15,59 @@
1415
}
1516
}
1617

17-
.p-megamenu-item>.p-megamenu-item-content .p-menuitem-link {
18-
display: flex;
19-
align-items: center;
20-
padding: 0 16px;
21-
22-
>a,
23-
>div {
24-
flex-grow: 1;
25-
padding: 12px 0;
26-
display: flex;
27-
align-items: center;
18+
.p-megamenu-item>.p-megamenu-item-content {
19+
color: var(--megamenu-text-color)
20+
}
2821

29-
.p-menuitem-text {
30-
flex-grow: 1;
31-
}
32-
}
22+
.p-megamenu-item {
23+
padding: var(--padding-small);
3324
}
3425

35-
.p-megamenu-item:not(.orange-box)>.p-megamenu-item-content .p-menuitem-link {
26+
.p-megamenu-item>.p-megamenu-item-content .p-menuitem-link {
27+
--outline-width: var(--padding-tiny);
28+
--outline-offset: var(--padding-tiny);
29+
display: flex;
30+
align-items: center;
31+
border-radius: var(--border-radius);
32+
padding: var(--padding-small) .75rem;
33+
gap: var(--padding);
3634

37-
.p-menuitem-text,
38-
.p-menuitem-icon {
39-
color: var(--text-color);
40-
white-space: nowrap;
35+
&:focus-visible {
36+
outline: var(--outline-width) solid var(--blue-500);
37+
outline-offset: var(--outline-offset);
4138
}
4239
}
4340

44-
.p-megamenu-item:not(.p-highlight):not(.p-disabled)>.p-megamenu-item-content:hover {
41+
.p-megamenu-submenu>.p-megamenu-item:not(.p-highlight):not(.p-disabled):hover {
4542
background: var(--megamenu-hover-color);
4643
}
4744

4845
.p-megamenu-overlay {
4946
background: var(--megamenu-panel-color);
50-
min-width: fit-content;
51-
right: 0;
52-
left: auto;
53-
top: calc(var(--navbar2-height) - 7px);
47+
background-color: transparent;
48+
width: fit-content;
49+
pointer-events: none;
5450
border-radius: var(--border-radius);
5551
}
5652

57-
.p-megamenu-submenu-label {
58-
margin: 0;
59-
padding: 12px 20px;
60-
color: var(--text-color);
61-
font-weight: var(--big_text_label_font_weight);
62-
font-size: var(--big_text_label_font_size);
53+
.p-megamenu-submenu {
54+
margin-top: var(--padding-tiny);
55+
padding: var(--padding) var(--padding-small) var(--padding) var(--padding-small);
56+
background-color: var(--background-color);
57+
border: 1px solid var(--container-border-color);
58+
border-radius: var(--border-radius);
59+
font-weight: var(--standard_text_font_weight);
60+
pointer-events: auto;
61+
62+
.p-megamenu-item {
63+
position: relative;
64+
border-radius: var(--border-radius);
65+
white-space: nowrap;
66+
text-overflow: ellipsis;
67+
}
6368
}
6469

6570
.p-megamenu-submenu {
66-
padding: 8px 0;
6771
min-width: fit-content;
6872
}
6973

@@ -76,37 +80,26 @@
7680
color: var(--megamenu-text-color);
7781
}
7882
}
83+
}
84+
}
7985

80-
.p-megamenu-root-list>.p-megamenu-item {
81-
&:last-child {
82-
>.p-megamenu-item-content .p-menuitem-link {
83-
padding-right: 0;
84-
}
85-
}
86-
}
86+
&:not(.p-megamenu-mobile) {
87+
.p-megamenu-overlay {
8788

88-
>.p-megamenu-item {
89-
&:last-child {
90-
>.p-megamenu-item-content .p-menuitem-link {
91-
padding-right: 0;
92-
}
93-
}
89+
.p-megamenu-col-2,
90+
.p-megamenu-col-3,
91+
.p-megamenu-col-12 {
92+
width: fit-content;
9493
}
9594
}
9695

97-
.p-megamenu-root-list {
98-
>.p-megamenu-item {
99-
>.p-megamenu-item-content .p-menuitem-link .p-submenu-icon {
100-
margin-left: 8px;
101-
}
102-
103-
&:not(.p-highlight):not(.p-disabled)>.p-megamenu-item-content:hover {
104-
background: var(--container-background);
105-
106-
.p-menuitem-link>.p-menuitem-text {
107-
opacity: 0.8;
108-
}
109-
}
96+
.p-megamenu-item {
97+
.bc-header-mega-menu__item-button {
98+
font-size: 1rem;
99+
padding: var(--padding-small);
100+
height: unset;
101+
margin: 0;
102+
margin-right: var(--padding);
110103
}
111104
}
112105
}
@@ -115,7 +108,7 @@
115108
width: 100%;
116109
align-items: flex-end;
117110
flex-direction: column;
118-
padding: 0;
111+
padding-top: var(--padding);
119112

120113
.p-megamenu-button {
121114
opacity: 0;
@@ -135,7 +128,6 @@
135128
position: static;
136129
border-radius: 8px;
137130
padding: 0 var(--padding);
138-
margin: var(--padding-small);
139131
}
140132

141133
.p-megamenu-root-list>.p-megamenu-item>.p-megamenu-item-content .p-menuitem-link {
@@ -146,43 +138,15 @@
146138
color: var(--text-color);
147139
}
148140
}
149-
}
150141

151-
&:not(.p-megamenu-mobile) {
152-
.p-megamenu-overlay {
153-
154-
.p-megamenu-col-2,
155-
.p-megamenu-col-3,
156-
.p-megamenu-col-12 {
157-
width: fit-content;
158-
}
159-
}
160-
}
161-
162-
.p-megamenu-overlay {
163-
164-
.p-megamenu-col-2,
165-
.p-megamenu-col-3,
166-
.p-megamenu-col-12 {
167-
padding: 0;
168-
}
169-
}
170-
171-
.p-megamenu-item {
172-
&.orange-box {
173-
.p-menuitem-link {
174-
background-color: var(--primary-orange);
175-
border-radius: var(--border-radius);
176-
177-
.p-menuitem-text {
178-
color: var(--text-color-inverted);
179-
white-space: nowrap;
180-
}
181-
182-
&:hover {
183-
background-color: var(--primary-orange-hover);
184-
}
185-
}
142+
.bc-header-mega-menu__item-button {
143+
display: flex;
144+
font-size: 1rem;
145+
padding: var(--padding-small) .75rem;
146+
height: unset;
147+
width: 100%;
148+
margin: 0;
149+
justify-content: space-between;
186150
}
187151
}
188152
}

frontend/components/bc/header/BcHeaderMegaMenu.vue

Lines changed: 71 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<script setup lang="ts">
22
import type { MenuItem } from 'primevue/menuitem'
3+
import type { IconName } from '~/layers/base/app/components/BaseIcon.vue'
34
45
import {
56
mobileHeaderThreshold, smallHeaderThreshold,
@@ -28,36 +29,65 @@ const items = computed(() => {
2829
let list: MenuItem[] = []
2930
3031
list = [
32+
{
33+
items: [ [ {
34+
items: [
35+
{
36+
icon: 'key-filled',
37+
label: $t('header.megamenu.api_key_management'),
38+
url: '/user/settings#api',
39+
},
40+
{
41+
icon: 'book-filled',
42+
label: $t('header.megamenu.api_docs'),
43+
url: '/api/v1/docs',
44+
},
45+
{
46+
icon: 'coins',
47+
label: $t('header.megamenu.api_pricing'),
48+
url: '/pricing',
49+
},
50+
],
51+
} ] ],
52+
label: 'API',
53+
root: true,
54+
},
3155
{
3256
label: $t('header.megamenu.dashboard'),
57+
root: true,
3358
url: '/dashboard',
3459
},
3560
{
3661
label: $t('header.megamenu.explorer'),
62+
root: true,
3763
url: `${v1Domain}`,
38-
3964
},
4065
{
4166
label: $t('header.megamenu.premium'),
67+
root: true,
4268
url: '/premium',
4369
},
4470
...(hasV1Notifications.value
4571
? [
4672
{
4773
label: $t('header.megamenu.notifications_v1'),
74+
root: true,
4875
url: `${v1Domain}/user/notifications`,
4976
},
5077
{
5178
label: $t('header.megamenu.notifications_v2'),
79+
root: true,
5280
url: '/notifications',
5381
},
5482
]
5583
: [ {
5684
label: $t('header.megamenu.notifications'),
85+
root: true,
5786
url: '/notifications',
5887
} ]
5988
),
6089
]
90+
6191
if (isMobile.value) {
6292
if (isLoggedIn.value) {
6393
list.push({
@@ -98,44 +128,53 @@ defineExpose({
98128
:breakpoint
99129
>
100130
<template #item="{ item }">
101-
<span class="p-menuitem-link">
102-
<BcLink
103-
v-if="item.url"
104-
:to="item.url"
105-
:replace="route.path.startsWith(item.url)"
131+
<BcLink
132+
v-if="item.root && item.url"
133+
class="p-menuitem-link"
134+
:to="item.url"
135+
:replace="route.path.startsWith(item.url)"
136+
>
137+
<span
138+
:class="[item.class]"
139+
class="p-menuitem-text"
106140
>
107-
<span
108-
:class="[item.class]"
109-
class="p-menuitem-text"
110-
>
111-
<span>{{ item.label }}</span>
112-
</span>
113-
</BcLink>
114-
<div
115-
v-else
116-
class="pointer p-menuitem-text"
141+
<span>{{ item.label }}</span>
142+
</span>
143+
</BcLink>
144+
145+
<BcButton
146+
v-else-if="item.root"
147+
:class="[item.class, 'bc-header-mega-menu__item-button']"
148+
@click="item.command?.(null as any)"
149+
>
150+
{{ item.label }}
151+
<template #icon>
152+
<BaseIcon
153+
name="chevron-down"
154+
/>
155+
</template>
156+
</BcButton>
157+
158+
<BcLink
159+
v-else-if="item.url"
160+
:to="item.url"
161+
:replace="route.path.startsWith(item.url)"
162+
class="p-menuitem-link"
163+
>
164+
<BaseIcon
165+
:name="item.icon as IconName"
166+
/>
167+
<span
117168
:class="[item.class]"
118-
@click="item.command?.(null as any)"
169+
class="p-menuitem-text"
119170
>
120-
{{ item.label }}
121-
</div>
122-
</span>
171+
<span>{{ item.label }}</span>
172+
</span>
173+
</BcLink>
123174
</template>
124175
</PvMegaMenu>
125176
</ClientOnly>
126177
</template>
127178

128179
<style lang="scss" scoped>
129-
.iconSpacing {
130-
width: 25px;
131-
position: relative;
132-
133-
img,
134-
svg,
135-
i {
136-
position: absolute;
137-
transform: translateY(-50%);
138-
max-width: 16px;
139-
}
140-
}
141180
</style>

0 commit comments

Comments
 (0)