feat(editor): updated n8n-menu component (#4290)

* refactor(editor): N8N-4540 Main navigation layout rework (#4060)

*  Implemented new editor layout using css grid

*  Reworking main navigation layout, migrating some styling to css modules

*  Reworking main sidebar layout and responsiveness

* 💄 Minor type update

*  Updated editor grid layout so empty cells are collapsed (`fit-content`), fixed updates menu items styling

*  Implemented new user area look & feel in main sidebar

* 💄 Adjusting sidebar bottom padding when user area is not shown

* 💄 CSS cleanup/refactor + minor vue refactoring

*  Fixing overscoll issue in chrome and scrolling behaviour of the content view

* 👌 Addressing review feedback

*  Added collapsed and expanded versions of n8n logo

*  Updating infinite scrolling in templates view to work with the new layout

* 💄 Updating main sidebar expanded width and templates view left margin

* 💄 Updating main content height

* 💄 Adding global styles for scrollable views with centered content, minor updates to user area

*  Updating zoomToFit logic, lasso select box position and new nodes positioning

*  Fixing new node drop position now that mouse detection has been adjusted

* 👌 Updating templates view scroll to top logic and responsive padding, aligning menu items titles

* 💄 Moving template layout style from global css class to component level

*  Moved 'Workflows'  menu to node view header. Added new dropdown component for user area and the new WF menu

* 💄 Updating disabled states in new WF menu

* 💄 Initial stab at new sidebar styling

*  Finished main navigation restyling

*  Updating `zoomToFit` and centering logic

*  Adding updates menu item to settings sidebar

* 💄 Adding updates item to the settings sidebar and final touches on main sidebar style

* 💄 Removing old code & refactoring

* 💄 Minor CSS tweaks

* 💄 Opening credentials modal on sidebar menu item click. Minor CSS updates

* 💄 Updating sidebar expand/collapse animation

* 💄 Few more refinements of sidebar animation

* 👌 Addressing code review comments

*  Moved ActionDropdown component to design system

* 👌 Fixing bugs reported during code review and testing

* 👌 Addressing design review comments for the new sidebar

* ✔️ Updating `N8nActionDropdown` component tests

*  Remembering scroll position when going back to templates list

*  Updating zoomToFit logic to account for footer content

* 👌 Addressing latest sidebar review comments

*  New `n8n-menu-item` component

*  Implemented new `n8n-menu` design system component, updated menu items to support collapsed mode

* Minor update to n8n-menu storybook entry

* 💄 Updating collapsed sub-menu style. Fixing vue error on hover.

*  Changing IMenuItem from interface to type

*  Added new n8n-menu component to editor main sidebar

*  Finished main sidebar

*  Added new menus to setttings and credentials view

*  Implemented tab and router modes for n8n-menu

*  Implemented credentials menus using new n8n-menu component

* 💄 Finishing main and settings sidebar details, updating design system stories

* 💄 Adding injected items support to main sidebar, handling navigation errors, small tweaks

* ✔️ Fixing linting errors

* ✔️ Addressing typescript errors in design system components

*  Using design-system types in editor UI

* 💄 Add support for custom icon size in menu items

* 👌 Addressing code review and design review feedback

* 💄 Minor updates
This commit is contained in:
Milorad FIlipović
2022-10-10 18:17:39 +02:00
committed by GitHub
parent d47ff48fb6
commit 6af3ba75dc
15 changed files with 1107 additions and 778 deletions

View File

@@ -4,132 +4,51 @@
[$style.sideMenu]: true,
[$style.sideMenuCollapsed]: isCollapsed
}">
<div :class="{[$style.sideMenuWrapper]: true, [$style.expanded]: !isCollapsed}">
<div
id="collapse-change-button"
:class="{
['clickable']: true,
[$style.sideMenuCollapseButton]: true,
[$style.expandedButton]: !isCollapsed
}"
@click="toggleCollapse"
></div>
<n8n-menu :default-active="$route.path" @select="handleSelect" :collapse="isCollapsed">
<n8n-menu-item
index="logo"
:class="[$style.logoItem, $style.disableActiveStyle]"
>
<div
id="collapse-change-button"
:class="{ ['clickable']: true, [$style.sideMenuCollapseButton]: true, [$style.expandedButton]: !isCollapsed }"
@click="toggleCollapse">
</div>
<n8n-menu :items="mainMenuItems" :collapsed="isCollapsed" @select="handleSelect">
<template #header>
<div :class="$style.logo">
<img :src="basePath + (isCollapsed ? 'n8n-logo-collapsed.svg' : 'n8n-logo-expanded.svg')" :class="$style.icon" alt="n8n"/>
</n8n-menu-item>
<div :class="$style.sideMenuFlexContainer">
<div :class="$style.sideMenuUpper">
<MenuItemsIterator :items="sidebarMenuTopItems" :root="true"/>
<el-submenu
index="/workflow"
title="Workflow"
popperClass="sidebar-popper"
:class="{
[$style.workflowSubmenu]: true,
[$style.active]: $route.path === '/workflow'
}"
>
<template slot="title">
<font-awesome-icon icon="network-wired"/>&nbsp;
<span slot="title" class="item-title-root">{{ $locale.baseText('mainSidebar.workflows') }}</span>
</template>
<n8n-menu-item index="/workflow">
<template slot="title">
<font-awesome-icon icon="file"/>&nbsp;
<span slot="title" class="item-title">{{ $locale.baseText('mainSidebar.new') }}</span>
</template>
</n8n-menu-item>
<n8n-menu-item index="workflow-open" :class="$style.disableActiveStyle">
<template slot="title">
<font-awesome-icon icon="folder-open"/>&nbsp;
<span slot="title" class="item-title">{{ $locale.baseText('mainSidebar.open') }}</span>
</template>
</n8n-menu-item>
</el-submenu>
<n8n-menu-item v-if="isTemplatesEnabled" index="/templates" :class="$style.templatesSubmenu">
<font-awesome-icon icon="box-open"/>&nbsp;
<span slot="title" class="item-title-root">{{ $locale.baseText('mainSidebar.templates') }}</span>
</n8n-menu-item>
<n8n-menu-item index="/credentials" :class="$style.credentialsSubmenu">
<font-awesome-icon icon="key"/>
<span slot="title" class="item-title-root">{{ $locale.baseText('mainSidebar.credentials') }}</span>
</n8n-menu-item>
<n8n-menu-item index="executions" :class="[$style.disableActiveStyle, $style.executionsSubmenu]">
<font-awesome-icon icon="tasks"/>&nbsp;
<span slot="title" class="item-title-root">{{ $locale.baseText('mainSidebar.executions') }}</span>
</n8n-menu-item>
</div>
<div :class="$style.sideMenuLower">
<n8n-menu-item index="settings" v-if="canUserAccessSettings && currentUser" :class="$style.settingsSubmenu">
<font-awesome-icon icon="cog"/>&nbsp;
<span slot="title" class="item-title-root">{{ $locale.baseText('settings') }}</span>
</n8n-menu-item>
<el-submenu index="help" :class="[$style.helpMenu, $style.disableActiveStyle]" title="Help" popperClass="sidebar-popper">
<template slot="title">
<font-awesome-icon icon="question"/>&nbsp;
<span slot="title" class="item-title-root">{{ $locale.baseText('mainSidebar.help') }}</span>
</template>
<MenuItemsIterator :items="helpMenuItems" :afterItemClick="trackHelpItemClick" />
<n8n-menu-item index="help-about">
<template slot="title">
<font-awesome-icon :class="$style['about-icon']" icon="info"/>
<span slot="title" class="item-title">{{ $locale.baseText('mainSidebar.aboutN8n') }}</span>
</template>
</n8n-menu-item>
</el-submenu>
<MenuItemsIterator :items="sidebarMenuBottomItems" :root="true"/>
<div :class="{
[$style.footerMenuItems] : true,
[$style.loggedIn]: showUserArea,
}">
<n8n-menu-item index="updates" :class="$style.updatesSubmenu" v-if="hasVersionUpdates" @click="openUpdatesPanel">
<div :class="$style.giftContainer">
<GiftNotificationIcon />
</div>
<span slot="title" :class="['item-title-root', $style.updatesLabel]">
{{nextVersions.length > 99 ? '99+' : nextVersions.length}} update{{nextVersions.length > 1 ? 's' : ''}}
</span>
</n8n-menu-item>
<n8n-menu-item v-if="showUserArea" :class="$style.userSubmenu" index="">
<!-- This dropdown is only enabled when sidebar is collapsed -->
<el-dropdown :disabled="!isCollapsed" placement="right-end" trigger="click" @command="onUserActionToggle">
<div :class="{[$style.avatar]: true, ['clickable']: isCollapsed }">
<n8n-avatar :firstName="currentUser.firstName" :lastName="currentUser.lastName" size="small" />
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="settings">{{ $locale.baseText('settings') }}</el-dropdown-item>
<el-dropdown-item command="logout">{{ $locale.baseText('auth.signout') }}</el-dropdown-item>
</el-dropdown-menu>
</div>
</el-dropdown>
<div slot="title" :class="['item-title-root', $style.username ]" v-if="!isCollapsed">
<span :title="currentUser.fullName" :class="$style.fullName">{{currentUser.fullName}}</span>
<div :class="{[$style.userActions]: true, ['user-actions']: true }">
<n8n-action-dropdown :items="userMenuItems" placement="top-start" @select="onUserActionToggle" />
</div>
</div>
</n8n-menu-item>
</div>
</template>
<template #menuSuffix v-if="hasVersionUpdates">
<div :class="$style.updates" @click="openUpdatesPanel">
<div :class="$style.giftContainer">
<GiftNotificationIcon />
</div>
<n8n-text :class="{['ml-xs']: true, [$style.expanded]: fullyExpanded }" color="text-base">
{{ nextVersions.length > 99 ? '99+' : nextVersions.length}} update{{nextVersions.length > 1 ? 's' : '' }}
</n8n-text>
</div>
</template>
<template #footer v-if="showUserArea">
<div :class="$style.userArea">
<div class="ml-3xs">
<!-- This dropdown is only enabled when sidebar is collapsed -->
<el-dropdown :disabled="!isCollapsed" placement="right-end" trigger="click" @command="onUserActionToggle">
<div :class="{[$style.avatar]: true, ['clickable']: isCollapsed }">
<n8n-avatar :firstName="currentUser.firstName" :lastName="currentUser.lastName" size="small" />
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="settings">{{ $locale.baseText('settings') }}</el-dropdown-item>
<el-dropdown-item command="logout">{{ $locale.baseText('auth.signout') }}</el-dropdown-item>
</el-dropdown-menu>
</div>
</el-dropdown>
</div>
<div :class="{ ['ml-2xs']: true, [$style.userName]: true, [$style.expanded]: fullyExpanded }">
<n8n-text size="small" :bold="true" color="text-dark">{{currentUser.fullName}}</n8n-text>
</div>
<div :class="{ [$style.userActions]: true, [$style.expanded]: fullyExpanded }">
<n8n-action-dropdown :items="userMenuItems" placement="top-start" @select="onUserActionToggle" />
</div>
</div>
</n8n-menu>
</div>
</template>
</n8n-menu>
</div>
</template>
<script lang="ts">
@@ -151,7 +70,6 @@ import { workflowRun } from '@/components/mixins/workflowRun';
import mixins from 'vue-typed-mixins';
import { mapGetters } from 'vuex';
import MenuItemsIterator from './MenuItemsIterator.vue';
import {
MODAL_CANCEL,
MODAL_CLOSE,
@@ -181,22 +99,12 @@ export default mixins(
ExecutionsList,
GiftNotificationIcon,
WorkflowSettings,
MenuItemsIterator,
},
data () {
return {
// @ts-ignore
basePath: this.$store.getters.getBaseUrl,
userMenuItems: [
{
id: 'settings',
label: this.$locale.baseText('settings'),
},
{
id: 'logout',
label: this.$locale.baseText('auth.signout'),
},
],
fullyExpanded: false,
};
},
computed: {
@@ -223,61 +131,154 @@ export default mixins(
showUserArea(): boolean {
return this.isUserManagementEnabled && this.canUserAccessSidebarUserInfo && this.currentUser;
},
helpMenuItems (): object[] {
return [
{
id: 'quickstart',
type: 'link',
properties: {
href: 'https://www.youtube.com/watch?v=RpjQTGKm-ok',
title: this.$locale.baseText('mainSidebar.helpMenuItems.quickstart'),
icon: 'video',
newWindow: true,
},
},
{
id: 'docs',
type: 'link',
properties: {
href: 'https://docs.n8n.io',
title: this.$locale.baseText('mainSidebar.helpMenuItems.documentation'),
icon: 'book',
newWindow: true,
},
},
{
id: 'forum',
type: 'link',
properties: {
href: 'https://community.n8n.io',
title: this.$locale.baseText('mainSidebar.helpMenuItems.forum'),
icon: 'users',
newWindow: true,
},
},
{
id: 'examples',
type: 'link',
properties: {
href: 'https://docs.n8n.io/courses',
title: this.$locale.baseText('mainSidebar.helpMenuItems.course'),
icon: 'graduation-cap',
newWindow: true,
},
},
];
},
workflowExecution (): IExecutionResponse | null {
return this.$store.getters.getWorkflowExecution;
},
sidebarMenuTopItems(): IMenuItem[] {
return this.$store.getters.sidebarMenuItems.filter((item: IMenuItem) => item.position === 'top');
userMenuItems (): object[] {
return [
{
id: 'settings',
label: this.$locale.baseText('settings'),
},
{
id: 'logout',
label: this.$locale.baseText('auth.signout'),
},
];
},
sidebarMenuBottomItems(): IMenuItem[] {
return this.$store.getters.sidebarMenuItems.filter((item: IMenuItem) => item.position === 'bottom');
mainMenuItems (): IMenuItem[] {
const items: IMenuItem[] = [];
const injectedItems = this.$store.getters.sidebarMenuItems as IMenuItem[];
if (injectedItems && injectedItems.length > 0) {
for(const item of injectedItems) {
items.push(
{
id: item.id,
// @ts-ignore
icon: item.properties ? item.properties.icon : '',
// @ts-ignore
label: item.properties ? item.properties.title : '',
position: item.position,
activateOnRouteNames: [ VIEWS.TEMPLATES ],
type: item.properties?.href ? 'link' : 'regular',
properties: item.properties,
} as IMenuItem,
);
}
};
const regularItems: IMenuItem[] = [
{
id: 'workflows',
icon: 'network-wired',
label: this.$locale.baseText('mainSidebar.workflows'),
position: 'top',
activateOnRouteNames: [ VIEWS.NEW_WORKFLOW, VIEWS.WORKFLOWS, VIEWS.WORKFLOW ],
children: [
{
id: 'workflow',
label: this.$locale.baseText('mainSidebar.new'),
icon: 'file',
activateOnRouteNames: [ VIEWS.NEW_WORKFLOW ],
},
{
id: 'workflow-open',
label: this.$locale.baseText('mainSidebar.open'),
icon: 'folder-open',
},
],
},
{
id: 'templates',
icon: 'box-open',
label: this.$locale.baseText('mainSidebar.templates'),
position: 'top',
available: this.isTemplatesEnabled,
activateOnRouteNames: [ VIEWS.TEMPLATES ],
},
{
id: 'credentials',
icon: 'key',
label: this.$locale.baseText('mainSidebar.credentials'),
customIconSize: 'medium',
position: 'top',
activateOnRouteNames: [ VIEWS.CREDENTIALS ],
},
{
id: 'executions',
icon: 'tasks',
label: this.$locale.baseText('mainSidebar.executions'),
position: 'top',
},
{
id: 'settings',
icon: 'cog',
label: this.$locale.baseText('settings'),
position: 'bottom',
available: this.canUserAccessSettings && this.currentUser,
activateOnRouteNames: [ VIEWS.USERS_SETTINGS, VIEWS.API_SETTINGS, VIEWS.PERSONAL_SETTINGS ],
},
{
id: 'help',
icon: 'question',
label: 'Help',
position: 'bottom',
children: [
{
id: 'quickstart',
icon: 'video',
label: this.$locale.baseText('mainSidebar.helpMenuItems.quickstart'),
type: 'link',
properties: {
href: 'https://www.youtube.com/watch?v=RpjQTGKm-ok',
newWindow: true,
},
},
{
id: 'docs',
icon: 'book',
label: this.$locale.baseText('mainSidebar.helpMenuItems.documentation'),
type: 'link',
properties: {
href: 'https://docs.n8n.io',
newWindow: true,
},
},
{
id: 'forum',
icon: 'users',
label: this.$locale.baseText('mainSidebar.helpMenuItems.forum'),
type: 'link',
properties: {
href: 'https://community.n8n.io',
newWindow: true,
},
},
{
id: 'examples',
icon: 'graduation-cap',
label: this.$locale.baseText('mainSidebar.helpMenuItems.course'),
type: 'link',
properties: {
href: 'https://www.youtube.com/watch?v=RpjQTGKm-ok',
newWindow: true,
},
},
{
id: 'about',
icon: 'info',
label: this.$locale.baseText('mainSidebar.aboutN8n'),
position: 'bottom',
},
],
},
];
return [ ...items, ...regularItems ];
},
},
mounted() {
this.fullyExpanded = !this.isCollapsed;
if (this.$refs.user) {
this.$externalHooks().run('mainSidebar.mounted', { userRef: this.$refs.user });
}
@@ -320,13 +321,21 @@ export default mixins(
},
toggleCollapse () {
this.$store.commit('ui/toggleSidebarMenuCollapse');
// When expanding, delay showing some element to ensure smooth animation
if (!this.isCollapsed) {
setTimeout(() => {
this.fullyExpanded = !this.isCollapsed;
}, 300);
} else {
this.fullyExpanded = !this.isCollapsed;
}
},
openUpdatesPanel() {
this.$store.dispatch('ui/openModal', VERSIONS_MODAL_KEY);
},
async handleSelect (key: string) {
switch (key) {
case '/workflow': {
case 'workflow': {
await this.createNewWorkflow();
break;
}
@@ -334,14 +343,16 @@ export default mixins(
this.$store.dispatch('ui/openModal', WORKFLOW_OPEN_MODAL_KEY);
break;
}
case '/templates': {
case 'templates': {
if (this.$router.currentRoute.name !== VIEWS.TEMPLATES) {
this.$router.push({ name: VIEWS.TEMPLATES });
}
break;
}
case '/credentials': {
this.$router.push({name: VIEWS.CREDENTIALS});
case 'credentials': {
if (this.$router.currentRoute.name !== VIEWS.CREDENTIALS) {
this.$router.push({name: VIEWS.CREDENTIALS});
}
break;
}
case 'executions': {
@@ -352,15 +363,24 @@ export default mixins(
const defaultRoute = this.findFirstAccessibleSettingsRoute();
if (defaultRoute) {
const routeProps = this.$router.resolve({ name: defaultRoute });
this.$router.push(routeProps.route.path);
if (this.$router.currentRoute.name !== defaultRoute) {
this.$router.push(routeProps.route.path);
}
}
break;
}
case 'help-about': {
case 'about': {
this.trackHelpItemClick('about');
this.$store.dispatch('ui/openModal', ABOUT_MODAL_KEY);
break;
}
case 'quickstart':
case 'docs':
case 'forum':
case 'examples' : {
this.trackHelpItemClick(key);
break;
}
default: break;
}
},
@@ -444,162 +464,34 @@ export default mixins(
});
</script>
<style lang="scss">
#side-menu {
.el-menu {
--menu-item-active-background-color: var(--color-foreground-base);
--menu-item-active-font-color: var(--color-text-dark);
--menu-item-hover-fill: var(--color-foreground-base);
--menu-item-hover-font-color: var(--color-text-dark);
--menu-item-height: 35px;
--submenu-item-height: 27px;
.el-icon-arrow-down {
font-weight: bold;
right: 12px;
&:hover {
color: var(--color-primary);
}
}
.el-menu-item:hover, .el-submenu__title:hover, .el-menu-item.is-active {
svg {
color: var(--color-text-dark);
}
}
.el-menu-item, .el-menu-item .el-tooltip, .el-submenu__title {
padding: 0 8px !important;
}
.el-menu-item, .el-submenu__title {
margin: 8px 0;
border-radius: var(--border-radius-base);
user-select: none;
.item-title-root {
position: absolute;
left: 45px;
}
svg {
color: var(--color-text-light);
}
}
.el-submenu {
.el-menu-item {
height: var(--menu-item-height);
line-height: var(--menu-item-height);
padding-left: var(--spacing-l) !important;
min-width: auto;
svg {
width: var(--spacing-m);
}
}
.el-menu .el-menu-item {
height: var(--submenu-item-height);
margin: 4px 0 !important;
.item-title {
position: absolute;
left: 60px;
}
}
}
}
}
.sidebar-popper{
.el-menu-item {
--menu-item-height: 35px;
--submenu-item-height: 27px;
--menu-item-hover-fill: var(--color-foreground-base);
border-radius: var(--border-radius-base);
margin: 0 var(--spacing-2xs);
.item-title {
position: absolute;
left: 55px;
}
.svg-inline--fa {
color: var(--color-text-light);
position: relative;
right: -3px;
}
&:hover {
.svg-inline--fa {
color: var(--color-text-dark);
}
}
}
}
</style>
<style lang="scss" module>
.sideMenu {
height: 100%;
&.sideMenuCollapsed {
.fullName,
:global(.item-title-root),
:global(.el-menu--collapse) :global(.el-submenu__icon-arrow),
:global(.el-icon-arrow-down) {
display: none;
}
.active {
background-color: var(--color-foreground-base);
border-radius: var(--border-radius-base);
svg { color: var(--color-text-dark) !important; }
}
.userSubmenu::before {
width: 160%;
}
}
svg:global(.svg-inline--fa) {
position: relative;
left: 3px;
}
svg:global(.svg-inline--fa.fa-home) { left: 4px; }
.executionsSubmenu svg:global(.svg-inline--fa),
.credentialsSubmenu svg:global(.svg-inline--fa),
.updatesSubmenu svg:global(.svg-inline--fa),
.settingsSubmenu svg:global(.svg-inline--fa)
{ left: 5px !important; }
.helpMenu{
svg:global(.svg-inline--fa) { left: 6px !important; }
:global(.el-menu--inline) { margin-bottom: 8px; }
}
}
.sideMenuWrapper {
position: relative;
height: 100%;
width: $sidebar-width;
border-right: var(--border-width-base) var(--border-style-base) var(--color-foreground-base);
transition: width 150ms ease-in-out;
width: $sidebar-expanded-width;
.logo {
height: $header-height;
display: flex;
align-items: center;
padding: var(--spacing-xs);
&.expanded {
width: $sidebar-expanded-width;
.icon {
img {
position: relative;
left: 16px;
left: 1px;
height: 20px;
}
}
ul { height: 100%; }
&.sideMenuCollapsed {
width: $sidebar-width;
.logo img {
left: 0;
}
}
}
.sideMenuCollapseButton {
@@ -645,167 +537,60 @@ export default mixins(
}
}
.sideMenuFlexContainer {
.updates {
display: flex;
flex-direction: column;
justify-content: space-between;
height: calc(100% - $header-height);
padding: var(--spacing-5xs) 0;
}
align-items: center;
height: 26px;
cursor: pointer;
.sideMenuUpper, .sideMenuLower {
padding: 0 var(--spacing-xs);
}
svg { color: var(--color-text-base) !important; }
span {
display: none;
&.expanded { display: initial; }
}
li:global(.is-active) {
.sideMenuLower &, &.disableActiveStyle {
background-color: initial;
color: var(--color-text-base);
svg {
color: var(--color-text-base) !important;
}
&:hover {
background-color: var(--color-foreground-base);
svg {
color: var(--color-text-dark) !important;
}
&:global(.el-submenu) {
background-color: unset;
}
&:hover {
&, & svg {
color: var(--color-text-dark) !important;
}
}
}
.logoItem {
.userArea {
display: flex;
justify-content: space-between;
height: $header-height;
line-height: $header-height;
margin: 0 !important;
border-radius: 0 !important;
border-bottom: var(--border-width-base) var(--border-style-base) var(--color-background-xlight);
cursor: default;
padding: var(--spacing-xs);
align-items: center;
height: 60px;
border-top: var(--border-width-base) var(--border-style-base) var(--color-foreground-base);
&:hover, &:global(.is-active):hover {
background-color: initial !important;
}
.userName {
display: none;
overflow: hidden;
width: 100px;
white-space: nowrap;
text-overflow: ellipsis;
* { vertical-align: middle; }
.icon {
height: 18px;
position: relative;
left: 6px;
}
}
.footerMenuItems {
display: flex;
flex-grow: 1;
flex-direction: column;
justify-content: flex-end;
padding-bottom: var(-spacing-m);
&.loggedIn {
padding-bottom: var(--spacing-xs);
}
}
.aboutIcon {
margin-left: 5px;
}
.updatesSubmenu {
margin-top: 0 !important;
.updatesLabel {
font-size: var(--font-size-xs);
}
.giftContainer {
display: flex;
justify-content: flex-start;
align-items: center;
height: 100%;
width: 100%;
div > div { right: -.5em; }
}
}
.userSubmenu {
position: relative;
cursor: default;
padding: var(--spacing-xs) !important;
margin: 0 !important;
// Fake border-top on user area
&::before {
width: 114%;
border-top: var(--border-width-base) var(--border-style-base) var(--color-foreground-base);
content: "";
position: absolute;
top: 0;
left: -12px;
}
&:hover, &:global(.is-active) {
background-color: initial !important;
.userActions svg {
color: var(--color-text-base) !important;
&.expanded {
display: initial;
}
}
.avatar {
position: relative;
left: -2px;
display: flex;
align-items: center;
justify-content: center;
padding-top: 16px;
cursor: default;
}
.username {
position: relative !important;
display: flex !important;
left: 9px !important;
justify-content: space-between;
align-items: center;
font-weight: var(--font-weight-bold);
font-size: var(--font-size-2xs);
padding-top: var(--spacing-s);
cursor: default;
.fullName {
width: 99px;
span {
overflow: hidden;
text-overflow: ellipsis;
color: var(--color-text-dark);
}
}
.userActions {
position: relative;
left: -1px;
cursor: pointer;
display: none;
&:hover {
svg { color: initial; }
&.expanded {
display: initial;
}
}
}
.userActionsMenu {
margin-left: 25px !important;
}
@media screen and (max-height: 470px) {
.helpMenu { display: none; }
:global(#help) { display: none; }
}
</style>