From 0b4b8128dec02153ca51f6c3b74154ade7d281a7 Mon Sep 17 00:00:00 2001 From: Tom Butcher Date: Fri, 18 Sep 2026 15:03:19 +0100 Subject: [PATCH] Enhance Dashboard Styles and Navigation with Improved Layout Adjustments - Added new CSS styles for dashboard menu container and tabs, improving visual alignment and spacing. - Introduced logic to manage scroll edge fades for better user experience during tab navigation. - Adjusted padding and margin properties for dashboard elements to enhance overall aesthetics and usability. - Reformatted component code for improved readability and consistency. --- assets/stylesheets/App.css | 96 +++++++++++++------ .../Dashboard/common/DashboardNavigation.jsx | 70 +++++++++----- .../Dashboard/common/DashboardTabs.jsx | 23 ++++- 3 files changed, 136 insertions(+), 53 deletions(-) diff --git a/assets/stylesheets/App.css b/assets/stylesheets/App.css index 1d167b98..73a10ebe 100644 --- a/assets/stylesheets/App.css +++ b/assets/stylesheets/App.css @@ -185,6 +185,10 @@ bottom: 0; } +.dashboard-menu-container-navigation-labels:after { + right: -6px; +} + .electron-navigation-leading, .electron-navigation-trailing { align-self: stretch; @@ -3481,27 +3485,43 @@ body.objectKanbanColumnResizing * { position: relative; } +.dashboard-tabs-wrap .simplebar-content-wrapper { + overscroll-behavior-x: none; +} + .dashboard-tabs-wrap .simplebar-mask { - --tab-mask-left: 0px; - --tab-mask-right: 0px; + --tab-mask-left: 4px; + --tab-mask-right: 4px; + --tab-mask-fade-left: var(--tab-mask-fade); + --tab-mask-fade-right: var(--tab-mask-fade); -webkit-clip-path: inset(0 var(--tab-mask-right) 0 var(--tab-mask-left)); clip-path: inset(0 var(--tab-mask-right) 0 var(--tab-mask-left)); -webkit-mask-image: linear-gradient( to right, transparent var(--tab-mask-left), - #000 calc(var(--tab-mask-left) + var(--tab-mask-fade)), - #000 calc(100% - var(--tab-mask-right) - var(--tab-mask-fade)), + #000 calc(var(--tab-mask-left) + var(--tab-mask-fade-left)), + #000 calc(100% - var(--tab-mask-right) - var(--tab-mask-fade-right)), transparent calc(100% - var(--tab-mask-right)) ); mask-image: linear-gradient( to right, transparent var(--tab-mask-left), - #000 calc(var(--tab-mask-left) + var(--tab-mask-fade)), - #000 calc(100% - var(--tab-mask-right) - var(--tab-mask-fade)), + #000 calc(var(--tab-mask-left) + var(--tab-mask-fade-left)), + #000 calc(100% - var(--tab-mask-right) - var(--tab-mask-fade-right)), transparent calc(100% - var(--tab-mask-right)) ); } +.dashboard-tabs[data-at-start] .dashboard-tabs-wrap .simplebar-mask { + --tab-mask-left: 0px; + --tab-mask-fade-left: 0px; +} + +.dashboard-tabs[data-at-end] .dashboard-tabs-wrap .simplebar-mask { + --tab-mask-right: 0px; + --tab-mask-fade-right: 0px; +} + .dashboard-tabs-wrap::before, .dashboard-tabs-wrap::after { content: ''; @@ -3572,7 +3592,7 @@ body.objectKanbanColumnResizing * { } .dashboard-tab-item-container:first-child:before { - left: -14px; + left: -20px; } .dashboard-tab-item-container:last-child:before { @@ -3662,14 +3682,25 @@ body.objectKanbanColumnResizing * { border-radius: 12px 12px 0 0; } +.dashboard-tab-item-active:before { + content: ''; + position: absolute; + top: 0px; + left: 0px; + right: 0px; + bottom: 21px; + border-radius: 11px 11px 0 0; + z-index: -2; + background: var(--color-layout-background); +} + .dashboard-tab-item-active:after { content: ''; position: absolute; - top: 1px; + top: 14px; left: 1px; right: 1px; bottom: -1px; - border-radius: 9px 9px 0 0; z-index: -2; background: var(--color-layout-background); } @@ -3699,6 +3730,10 @@ body.objectKanbanColumnResizing * { --tab-corner-center: calc( var(--tab-corner-size) - var(--tab-corner-inset) - var(--tab-corner-radius) ); + --tab-fill-nudge-x: 3px; + --tab-fill-nudge-y: 4px; + --tab-fill-circle-x: calc(var(--tab-corner-center) + var(--tab-fill-nudge-x)); + --tab-fill-circle-y: calc(var(--tab-corner-size) - var(--tab-corner-radius)); position: absolute; bottom: -1px; width: var(--tab-corner-size); @@ -3718,35 +3753,39 @@ body.objectKanbanColumnResizing * { .dashboard-tab-item-corner-fill { position: absolute; - inset: 0; + width: 26px; + height: 26px; + bottom: calc(-1 * var(--tab-fill-nudge-y)); background: var(--color-layout-background); -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; } .dashboard-tab-item-corner-left .dashboard-tab-item-corner-fill { + left: calc(-1 * var(--tab-fill-nudge-x)); -webkit-mask-image: radial-gradient( - circle at var(--tab-corner-center) var(--tab-corner-center), - transparent calc(var(--tab-corner-radius) - 0.5px), - #000 calc(var(--tab-corner-radius) - 0.5px) + circle at var(--tab-fill-circle-x) var(--tab-fill-circle-y), + transparent var(--tab-corner-radius), + #000 var(--tab-corner-radius) ); mask-image: radial-gradient( - circle at var(--tab-corner-center) var(--tab-corner-center), - transparent calc(var(--tab-corner-radius) - 0.5px), - #000 calc(var(--tab-corner-radius) - 0.5px) + circle at var(--tab-fill-circle-x) var(--tab-fill-circle-y), + transparent var(--tab-corner-radius), + #000 var(--tab-corner-radius) ); } .dashboard-tab-item-corner-right .dashboard-tab-item-corner-fill { + right: calc(-1 * var(--tab-fill-nudge-x)); -webkit-mask-image: radial-gradient( - circle at calc(100% - var(--tab-corner-center)) var(--tab-corner-center), - transparent calc(var(--tab-corner-radius) - 0.5px), - #000 calc(var(--tab-corner-radius) - 0.5px) + circle at calc(100% - var(--tab-fill-circle-x)) var(--tab-fill-circle-y), + transparent var(--tab-corner-radius), + #000 var(--tab-corner-radius) ); mask-image: radial-gradient( - circle at calc(100% - var(--tab-corner-center)) var(--tab-corner-center), - transparent calc(var(--tab-corner-radius) - 0.5px), - #000 calc(var(--tab-corner-radius) - 0.5px) + circle at calc(100% - var(--tab-fill-circle-x)) var(--tab-fill-circle-y), + transparent var(--tab-corner-radius), + #000 var(--tab-corner-radius) ); } @@ -3797,7 +3836,9 @@ body.objectKanbanColumnResizing * { .dashboard-tabs[data-sticky-edge] .dashboard-tab-item-container:before, .dashboard-tabs[data-sticky-edge] .dashboard-tabs-add-button-container:before, .dashboard-tabs[data-sticky-edge] .dashboard-tabs-wrap::before, -.dashboard-tabs[data-sticky-edge] .dashboard-tabs-wrap::after { +.dashboard-tabs[data-sticky-edge] .dashboard-tabs-wrap::after, +.dashboard-tabs[data-at-start] .dashboard-tabs-wrap::before, +.dashboard-tabs[data-at-end] .dashboard-tabs-wrap::after { content: none; display: none; } @@ -3897,9 +3938,10 @@ body.objectKanbanColumnResizing * { } .dashboard-tabs-add-button { - padding-inline: 4px; - min-width: 20px; - margin-top: 2px; + padding-inline: 5px; + min-width: 22px; + margin-top: 5px; + margin-right: 5px; } .dashboard-tabs-add-button-container { @@ -3911,7 +3953,7 @@ body.objectKanbanColumnResizing * { .dashboard-tabs-add-button-container:before { content: ''; position: absolute; - left: 12px; + left: 15px; right: 0; bottom: 0; border-bottom: 1px solid var(--color-header-border); diff --git a/src/components/Dashboard/common/DashboardNavigation.jsx b/src/components/Dashboard/common/DashboardNavigation.jsx index 93e4d1a1..1398afd4 100644 --- a/src/components/Dashboard/common/DashboardNavigation.jsx +++ b/src/components/Dashboard/common/DashboardNavigation.jsx @@ -1,5 +1,12 @@ // DashboardNavigation.js -import { useContext, useEffect, useState, useMemo, useCallback, memo } from 'react' +import { + useContext, + useEffect, + useState, + useMemo, + useCallback, + memo +} from 'react' import PropTypes from 'prop-types' import { Menu, @@ -12,6 +19,7 @@ import { Typography, Popover } from 'antd' +import classNames from 'classnames' import { AuthContext } from '../context/AuthContext' import { SpotlightContext } from '../context/SpotlightContext' import { ApiServerContext } from '../context/ApiServerContext' @@ -89,7 +97,11 @@ const NAV_OVERFLOW_BUTTON_STYLE = { marginBottom: '4px' } const navigationFadeClass = (visible) => `dashboard-navigation-fade${visible ? '' : ' dashboard-navigation-fade-hidden'}` -const NavigationFade = memo(function NavigationFade({ visible, children, style }) { +const NavigationFade = memo(function NavigationFade({ + visible, + children, + style +}) { return (
-
{menu}
- -
- -
- - ) -}) +const DashboardElectronCenterItems = memo( + function DashboardElectronCenterItems({ menu, showNavigationLabels }) { + return ( + <> +
+ {menu} +
+ +
+ +
+ + ) + } +) DashboardElectronCenterItems.propTypes = { menu: PropTypes.node, @@ -520,7 +538,11 @@ const DashboardNavigation = () => { }, [checkForUpdates]) const overflowedIndicator = useMemo( () => ( -