Refactor Dashboard Styles and Enhance Layout Consistency
All checks were successful
farmcontrol/farmcontrol-ui/pipeline/head This commit looks good

- Updated CSS styles for macOS vibrancy modes, adjusting background colors and adding new layout properties for improved visual clarity.
- Enhanced dashboard tab components with new corner fill elements and refined dimensions for better alignment and responsiveness.
- Modified DashboardNavigation and DashboardTabs components to improve layout handling and user interaction, including adjustments to padding and flex properties.
- Introduced transitions for non-active dashboard tab items to enhance user experience during interactions.
This commit is contained in:
Tom Butcher 2026-09-18 01:16:26 +01:00
parent d6c72c21e8
commit c39051a891
3 changed files with 155 additions and 45 deletions

View File

@ -158,19 +158,32 @@ html.macos-vibrancy .main-layout {
} }
html.macos-vibrancy .light-mode { html.macos-vibrancy .light-mode {
--color-layout-background: rgba(255, 255, 255, 0.88); --color-layout-background: rgba(255, 255, 255, 0.3);
} }
html.macos-vibrancy .dark-mode { html.macos-vibrancy .dark-mode {
--color-layout-background: rgba(0, 0, 0, 0.88); --color-layout-background: rgba(0, 0, 0, 0.3);
} }
html.macos-vibrancy .light-mode .ant-layout.main-content-layout { html.macos-vibrancy .light-mode .ant-layout.main-content-layout {
background: var(--color-layout-background) !important; background: var(--color-layout-background) !important;
position: relative;
} }
html.macos-vibrancy .dark-mode .ant-layout.main-content-layout { html.macos-vibrancy .dark-mode .ant-layout.main-content-layout {
background: var(--color-layout-background) !important; background: var(--color-layout-background) !important;
position: relative;
}
html.macos-vibrancy .dark-mode .ant-layout.main-content-layout:before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(10, 10, 10, 0.85) !important;
z-index: -1;
} }
html.macos-vibrancy .light-mode .ant-layout-sider { html.macos-vibrancy .light-mode .ant-layout-sider {
@ -213,11 +226,11 @@ html.macos-vibrancy
} }
html.macos-vibrancy .dark-mode .electron-navigation-wrapper { html.macos-vibrancy .dark-mode .electron-navigation-wrapper {
background: rgba(10, 10, 10, 0.9) !important; background: rgba(10, 10, 10, 0.85) !important;
} }
html.macos-vibrancy .light-mode .electron-navigation-wrapper { html.macos-vibrancy .light-mode .electron-navigation-wrapper {
background: rgba(255, 255, 255, 0.9) !important; background: rgba(255, 255, 255, 0.85) !important;
} }
html.macos-vibrancy .electron-navigation { html.macos-vibrancy .electron-navigation {
@ -1913,7 +1926,7 @@ body.objectKanbanColumnResizing * {
.electron-body .ant-modal-wrap, .electron-body .ant-modal-wrap,
.electron-body .ant-modal-mask, .electron-body .ant-modal-mask,
.electron-body .ant-drawer { .electron-body .ant-drawer {
top: 41px; top: 42px;
} }
@keyframes h-progress-macos-wave { @keyframes h-progress-macos-wave {
@ -3372,6 +3385,7 @@ body.objectKanbanColumnResizing * {
flex: 1; flex: 1;
min-width: 0; min-width: 0;
align-self: stretch; align-self: stretch;
height: 42px;
} }
.dashboard-tabs-wrap { .dashboard-tabs-wrap {
@ -3387,6 +3401,9 @@ body.objectKanbanColumnResizing * {
.dashboard-tabs-inner { .dashboard-tabs-inner {
width: max-content; width: max-content;
height: 100%; height: 100%;
min-width: fit-content;
width: 100%;
overflow: hidden;
align-items: flex-start; align-items: flex-start;
box-sizing: border-box; box-sizing: border-box;
} }
@ -3396,19 +3413,19 @@ body.objectKanbanColumnResizing * {
display: flex; display: flex;
align-items: flex-start; align-items: flex-start;
gap: 4px; gap: 4px;
padding-inline: 12px; padding-left: 12px;
height: 100%; height: 100%;
max-height: 42px; max-height: 42px;
} }
.dashboard-tab-item-container { .dashboard-tab-item-container {
height: 43px; height: 42px;
position: relative; position: relative;
} }
.dashboard-tab-item-container-active { .dashboard-tab-item-container-active {
border-bottom: none; border-bottom: none;
height: 43px; height: 42px;
} }
.dashboard-tab-item-container:before { .dashboard-tab-item-container:before {
@ -3421,12 +3438,22 @@ body.objectKanbanColumnResizing * {
border-bottom: 1px solid var(--color-header-border); border-bottom: 1px solid var(--color-header-border);
} }
.dashboard-tab-item-container:first-child:before {
left: -12px;
}
.dashboard-tab-item-container:last-child:before {
right: -20px;
}
.dashboard-tab-item-container-active + .dashboard-tab-item-container:before { .dashboard-tab-item-container-active + .dashboard-tab-item-container:before {
left: 16px; left: 16px;
} }
.dashboard-tabs-list:has(+ .dashboard-tab-item-container-active):before { .dashboard-tab-item-container:has(
right: 9.5px; + .dashboard-tab-item-container-active
):before {
right: 16px;
} }
.dashboard-tab-item-container-active:before { .dashboard-tab-item-container-active:before {
@ -3453,10 +3480,6 @@ body.objectKanbanColumnResizing * {
color: inherit; color: inherit;
box-shadow: none; box-shadow: none;
outline: none; outline: none;
transition:
background 0.3s ease,
border-color 0.3s ease;
} }
.dashboard-tab-item-icon { .dashboard-tab-item-icon {
@ -3473,6 +3496,12 @@ body.objectKanbanColumnResizing * {
outline-offset: 2px; outline-offset: 2px;
} }
.dashboard-tab-item:not(.dashboard-tab-item-active) {
transition:
background 0.3s ease,
border-color 0.3s ease;
}
.dashboard-tab-item:not(.dashboard-tab-item-active):hover { .dashboard-tab-item:not(.dashboard-tab-item-active):hover {
background: var(--color-button-background); background: var(--color-button-background);
border: 1px solid border: 1px solid
@ -3490,7 +3519,7 @@ body.objectKanbanColumnResizing * {
padding-bottom: 5px; padding-bottom: 5px;
border-color: transparent; border-color: transparent;
border-radius: 12px 12px 0 0; border-radius: 12px 12px 0 0;
background: transparent; background: var(--color-layout-background);
} }
.dashboard-tab-item-outline-container { .dashboard-tab-item-outline-container {
@ -3509,18 +3538,22 @@ body.objectKanbanColumnResizing * {
border-radius: 12px 12px 0 0; border-radius: 12px 12px 0 0;
pointer-events: none; pointer-events: none;
opacity: 0; opacity: 0;
transition: opacity 0.3s ease;
} }
.dashboard-tab-item-corner { .dashboard-tab-item-corner {
--tab-corner-size: 22px;
--tab-corner-radius: 15.5px;
--tab-corner-inset: 1px;
--tab-corner-center: calc(
var(--tab-corner-size) - var(--tab-corner-inset) - var(--tab-corner-radius)
);
position: absolute; position: absolute;
bottom: -2px; bottom: -2px;
width: 22px; width: var(--tab-corner-size);
height: 22px; height: var(--tab-corner-size);
overflow: hidden; overflow: hidden;
pointer-events: none; pointer-events: none;
opacity: 0; opacity: 0;
transition: opacity 0.3s ease;
} }
.dashboard-tab-item-corner-left { .dashboard-tab-item-corner-left {
@ -3531,23 +3564,75 @@ body.objectKanbanColumnResizing * {
right: -21px; right: -21px;
} }
.dashboard-tab-item-corner-fill {
position: absolute;
top: 1px;
left: 2px;
right: 2px;
bottom: -1px;
background: var(--color-layout-background);
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
}
.dashboard-tab-item-corner-left .dashboard-tab-item-corner-fill {
-webkit-mask-image: radial-gradient(
circle var(--tab-corner-radius) at var(--tab-corner-center)
var(--tab-corner-center),
transparent var(--tab-corner-radius),
#000 var(--tab-corner-radius)
);
mask-image: radial-gradient(
circle var(--tab-corner-radius) at var(--tab-corner-center)
var(--tab-corner-center),
transparent var(--tab-corner-radius),
#000 var(--tab-corner-radius)
);
}
.dashboard-tab-item-corner-right .dashboard-tab-item-corner-fill {
-webkit-mask-image: radial-gradient(
circle var(--tab-corner-radius) at
calc(var(--tab-corner-radius) + var(--tab-corner-inset))
var(--tab-corner-center),
transparent var(--tab-corner-radius),
#000 var(--tab-corner-radius)
);
mask-image: radial-gradient(
circle var(--tab-corner-radius) at
calc(var(--tab-corner-radius) + var(--tab-corner-inset))
var(--tab-corner-center),
transparent var(--tab-corner-radius),
#000 var(--tab-corner-radius)
);
}
.dashboard-tab-item-corner-inner { .dashboard-tab-item-corner-inner {
position: absolute; position: absolute;
width: 48px; width: 48px;
height: 48px; height: 48px;
box-sizing: border-box; box-sizing: border-box;
border: 1px solid var(--color-header-border); border-radius: var(--tab-corner-radius);
border-radius: 15.5px; padding: 1px;
background: var(--color-header-border);
-webkit-mask:
linear-gradient(#fff 0 0) content-box,
linear-gradient(#fff 0 0);
-webkit-mask-composite: xor;
mask:
linear-gradient(#fff 0 0) content-box,
linear-gradient(#fff 0 0);
mask-composite: exclude;
} }
.dashboard-tab-item-corner-left .dashboard-tab-item-corner-inner { .dashboard-tab-item-corner-left .dashboard-tab-item-corner-inner {
bottom: 1px; bottom: var(--tab-corner-inset);
right: 1px; right: var(--tab-corner-inset);
} }
.dashboard-tab-item-corner-right .dashboard-tab-item-corner-inner { .dashboard-tab-item-corner-right .dashboard-tab-item-corner-inner {
bottom: 1px; bottom: var(--tab-corner-inset);
left: 1px; left: var(--tab-corner-inset);
} }
.dashboard-tab-item-active .dashboard-tab-item-outline, .dashboard-tab-item-active .dashboard-tab-item-outline,
@ -3557,10 +3642,11 @@ body.objectKanbanColumnResizing * {
.dashboard-tabs-label { .dashboard-tabs-label {
max-width: 280px; max-width: 280px;
margin-top: -2px;
} }
.dashboard-tabs-close { .dashboard-tabs-close {
position: relative;
z-index: 1;
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@ -3570,6 +3656,14 @@ body.objectKanbanColumnResizing * {
border-radius: 8px; border-radius: 8px;
color: var(--color-text-secondary, inherit); color: var(--color-text-secondary, inherit);
opacity: 0.7; opacity: 0.7;
cursor: pointer;
flex-shrink: 0;
}
.dashboard-tabs-close::before {
content: '';
position: absolute;
inset: -8px -8px -8px -6px;
} }
.dashboard-tabs-close:hover { .dashboard-tabs-close:hover {
@ -3583,6 +3677,21 @@ body.objectKanbanColumnResizing * {
margin-top: 2px; margin-top: 2px;
} }
.dashboard-tabs-add-button-container {
flex-grow: 1;
height: 42px;
position: relative;
}
.dashboard-tabs-add-button-container:before {
content: '';
position: absolute;
left: 12px;
right: 0;
bottom: 0;
border-bottom: 1px solid var(--color-header-border);
}
.dashboard-tab-item-dragging { .dashboard-tab-item-dragging {
opacity: 0.4; opacity: 0.4;
} }

View File

@ -473,7 +473,11 @@ const DashboardNavigation = () => {
className={`electron-navigation-wrapper ${electronDragClass}`} className={`electron-navigation-wrapper ${electronDragClass}`}
style={{ lineHeight: '40px', padding: '0 2px 0 2px' }} style={{ lineHeight: '40px', padding: '0 2px 0 2px' }}
> >
<Flex align='center' className='electron-navigation-leading'> <Flex
align='center'
className='electron-navigation-leading'
style={{ flexGrow: !showControls ? 1 : 0 }}
>
{navigationLeading} {navigationLeading}
{showControls && !isMobile ? menu : null} {showControls && !isMobile ? menu : null}
{showControls && !isMobile ? ( {showControls && !isMobile ? (
@ -481,8 +485,8 @@ const DashboardNavigation = () => {
type='vertical' type='vertical'
style={{ style={{
margin: showNavigationLabels margin: showNavigationLabels
? '3px 16px 0 4px' ? '3px 1px 0 4px'
: '3px 16px 0 0', : '3px 1px 0 0',
height: '14px' height: '14px'
}} }}
/> />

View File

@ -22,12 +22,14 @@ const DashboardTabChrome = () => (
className='dashboard-tab-item-corner dashboard-tab-item-corner-left' className='dashboard-tab-item-corner dashboard-tab-item-corner-left'
aria-hidden='true' aria-hidden='true'
> >
<span className='dashboard-tab-item-corner-fill' />
<span className='dashboard-tab-item-corner-inner' /> <span className='dashboard-tab-item-corner-inner' />
</span> </span>
<span <span
className='dashboard-tab-item-corner dashboard-tab-item-corner-right' className='dashboard-tab-item-corner dashboard-tab-item-corner-right'
aria-hidden='true' aria-hidden='true'
> >
<span className='dashboard-tab-item-corner-fill' />
<span className='dashboard-tab-item-corner-inner' /> <span className='dashboard-tab-item-corner-inner' />
</span> </span>
</> </>
@ -243,11 +245,7 @@ const DashboardTabs = () => {
onDragOver={handleStripDragOver} onDragOver={handleStripDragOver}
onDrop={handleStripDrop} onDrop={handleStripDrop}
> >
<ScrollBox <ScrollBox className='dashboard-tabs-wrap' horizontal>
className='dashboard-tabs-wrap'
horizontal
horizontalBottomPadding={0}
>
<Flex align='flex-start' gap={8} className='dashboard-tabs-inner'> <Flex align='flex-start' gap={8} className='dashboard-tabs-inner'>
<div <div
className={classNames('dashboard-tabs-list', { className={classNames('dashboard-tabs-list', {
@ -302,10 +300,7 @@ const DashboardTabs = () => {
> >
<DashboardTabChrome /> <DashboardTabChrome />
<span className='dashboard-tab-item-icon'> <span className='dashboard-tab-item-icon'>
<Icon <Icon style={{ fontSize: 14 }} color='secondary' />
style={{ fontSize: 14, marginTop: '-2px' }}
color='secondary'
/>
</span> </span>
<DashboardTabLabel tab={tab} onClose={closeTab} /> <DashboardTabLabel tab={tab} onClose={closeTab} />
</button> </button>
@ -313,13 +308,15 @@ const DashboardTabs = () => {
) )
})} })}
</div> </div>
<Button <div className='dashboard-tabs-add-button-container'>
type='text' <Button
size='small' type='text'
className='dashboard-tabs-add-button electrobun-webkit-app-region-no-drag' size='small'
onClick={addTab} className='dashboard-tabs-add-button electrobun-webkit-app-region-no-drag'
icon={<PlusIcon style={{ fontSize: 14, marginTop: 3 }} />} onClick={addTab}
/> icon={<PlusIcon style={{ fontSize: 14, marginTop: 3 }} />}
/>
</div>
</Flex> </Flex>
</ScrollBox> </ScrollBox>
</Flex> </Flex>