Refine Dashboard Styles and Tab Functionality for Enhanced User Experience
All checks were successful
farmcontrol/farmcontrol-ui/pipeline/head This commit looks good
All checks were successful
farmcontrol/farmcontrol-ui/pipeline/head This commit looks good
- Adjusted CSS styles for dashboard elements, including margin and positioning tweaks for improved layout and visual consistency. - Updated tab masking logic to enhance scrolling behavior and visual integration. - Removed unnecessary divider components to streamline the dashboard navigation structure. - Implemented new logic for handling tab scrolling, ensuring better responsiveness and user interaction.
This commit is contained in:
parent
0b4b8128de
commit
48d2b0d15a
@ -175,13 +175,14 @@
|
||||
position: relative;
|
||||
height: 42px;
|
||||
padding-top: 2px;
|
||||
margin-left: 8px;
|
||||
}
|
||||
.dashboard-menu-container:after {
|
||||
border-bottom: 1px solid var(--color-header-border);
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: -2px;
|
||||
left: -8px;
|
||||
right: 0px;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
@ -3483,6 +3484,10 @@ body.objectKanbanColumnResizing * {
|
||||
min-width: 0;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
--tab-mask-left: 4px;
|
||||
--tab-mask-right: 8px;
|
||||
--tab-mask-fade-left: var(--tab-mask-fade);
|
||||
--tab-mask-fade-right: var(--tab-mask-fade);
|
||||
}
|
||||
|
||||
.dashboard-tabs-wrap .simplebar-content-wrapper {
|
||||
@ -3490,10 +3495,6 @@ body.objectKanbanColumnResizing * {
|
||||
}
|
||||
|
||||
.dashboard-tabs-wrap .simplebar-mask {
|
||||
--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(
|
||||
@ -3512,12 +3513,12 @@ body.objectKanbanColumnResizing * {
|
||||
);
|
||||
}
|
||||
|
||||
.dashboard-tabs[data-at-start] .dashboard-tabs-wrap .simplebar-mask {
|
||||
.dashboard-tabs[data-at-start] .dashboard-tabs-wrap {
|
||||
--tab-mask-left: 0px;
|
||||
--tab-mask-fade-left: 0px;
|
||||
}
|
||||
|
||||
.dashboard-tabs[data-at-end] .dashboard-tabs-wrap .simplebar-mask {
|
||||
.dashboard-tabs[data-at-end] .dashboard-tabs-wrap {
|
||||
--tab-mask-right: 0px;
|
||||
--tab-mask-fade-right: 0px;
|
||||
}
|
||||
@ -3527,7 +3528,6 @@ body.objectKanbanColumnResizing * {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: var(--tab-mask-fade);
|
||||
height: 1px;
|
||||
pointer-events: none;
|
||||
z-index: 2;
|
||||
@ -3536,14 +3536,32 @@ body.objectKanbanColumnResizing * {
|
||||
|
||||
.dashboard-tabs-wrap::before {
|
||||
left: 0;
|
||||
-webkit-mask-image: linear-gradient(to right, #000, transparent);
|
||||
mask-image: linear-gradient(to right, #000, transparent);
|
||||
width: calc(var(--tab-mask-left) + var(--tab-mask-fade-left));
|
||||
-webkit-mask-image: linear-gradient(
|
||||
to right,
|
||||
#000 var(--tab-mask-left),
|
||||
transparent calc(var(--tab-mask-left) + var(--tab-mask-fade-left))
|
||||
);
|
||||
mask-image: linear-gradient(
|
||||
to right,
|
||||
#000 var(--tab-mask-left),
|
||||
transparent calc(var(--tab-mask-left) + var(--tab-mask-fade-left))
|
||||
);
|
||||
}
|
||||
|
||||
.dashboard-tabs-wrap::after {
|
||||
right: 0.2px;
|
||||
-webkit-mask-image: linear-gradient(to left, #000, transparent);
|
||||
mask-image: linear-gradient(to left, #000, transparent);
|
||||
width: calc(var(--tab-mask-right) + var(--tab-mask-fade-right));
|
||||
-webkit-mask-image: linear-gradient(
|
||||
to left,
|
||||
#000 var(--tab-mask-right),
|
||||
transparent calc(var(--tab-mask-right) + var(--tab-mask-fade-right))
|
||||
);
|
||||
mask-image: linear-gradient(
|
||||
to left,
|
||||
#000 var(--tab-mask-right),
|
||||
transparent calc(var(--tab-mask-right) + var(--tab-mask-fade-right))
|
||||
);
|
||||
}
|
||||
|
||||
.dashboard-tabs-wrap .simplebar-track.simplebar-vertical {
|
||||
|
||||
@ -78,14 +78,6 @@ const NAV_ELECTRON_CENTER_FADE_STYLE = {
|
||||
alignItems: 'center'
|
||||
}
|
||||
const NAV_ELECTRON_TABS_STYLE = { flex: 1, minWidth: 0, display: 'flex' }
|
||||
const NAV_ELECTRON_DIVIDER_STYLE_WITH_LABELS = {
|
||||
margin: '3px 1px 0 4px',
|
||||
height: '14px'
|
||||
}
|
||||
const NAV_ELECTRON_DIVIDER_STYLE = {
|
||||
margin: '3px 1px 0 0',
|
||||
height: '14px'
|
||||
}
|
||||
const NAV_TRAILING_FLEX_STYLE = { marginTop: '-2px', marginRight: '6px' }
|
||||
const NAV_TRAILING_SPACE_STYLE = { paddingTop: '2px', marginRight: '8px' }
|
||||
const NAV_SEARCH_BUTTON_STYLE = { marginTop: '4px' }
|
||||
@ -237,14 +229,7 @@ const DashboardElectronCenterItems = memo(
|
||||
>
|
||||
{menu}
|
||||
</div>
|
||||
<Divider
|
||||
type='vertical'
|
||||
style={
|
||||
showNavigationLabels
|
||||
? NAV_ELECTRON_DIVIDER_STYLE_WITH_LABELS
|
||||
: NAV_ELECTRON_DIVIDER_STYLE
|
||||
}
|
||||
/>
|
||||
|
||||
<div style={NAV_ELECTRON_TABS_STYLE}>
|
||||
<DashboardTabs />
|
||||
</div>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import PropTypes from 'prop-types'
|
||||
import { useCallback, useLayoutEffect, useRef, useState } from 'react'
|
||||
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'
|
||||
import { Button, Flex, Typography } from 'antd'
|
||||
import classNames from 'classnames'
|
||||
import ScrollBox from './ScrollBox'
|
||||
@ -177,17 +177,18 @@ const hideStickyClone = (cloneEl) => {
|
||||
|
||||
const setSimplebarMaskInset = (maskEl, edge, inset) => {
|
||||
if (!maskEl) return
|
||||
const wrapEl = maskEl.closest('.dashboard-tabs-wrap') || maskEl
|
||||
if (!edge) {
|
||||
maskEl.style.removeProperty('--tab-mask-left')
|
||||
maskEl.style.removeProperty('--tab-mask-right')
|
||||
wrapEl.style.removeProperty('--tab-mask-left')
|
||||
wrapEl.style.removeProperty('--tab-mask-right')
|
||||
return
|
||||
}
|
||||
if (edge === 'left') {
|
||||
maskEl.style.setProperty('--tab-mask-left', `${inset}px`)
|
||||
maskEl.style.removeProperty('--tab-mask-right')
|
||||
wrapEl.style.setProperty('--tab-mask-left', `${inset}px`)
|
||||
wrapEl.style.removeProperty('--tab-mask-right')
|
||||
} else {
|
||||
maskEl.style.removeProperty('--tab-mask-left')
|
||||
maskEl.style.setProperty('--tab-mask-right', `${inset}px`)
|
||||
wrapEl.style.removeProperty('--tab-mask-left')
|
||||
wrapEl.style.setProperty('--tab-mask-right', `${inset}px`)
|
||||
}
|
||||
}
|
||||
|
||||
@ -391,6 +392,8 @@ const useActiveTabStickyScroll = (activeTabId, tabs) => {
|
||||
const listRef = useRef(null)
|
||||
const cloneRef = useRef(null)
|
||||
const lineRef = useRef(null)
|
||||
const prevTabCountRef = useRef(tabs.length)
|
||||
const pendingScrollTabIdRef = useRef(null)
|
||||
const tabLayoutKey = `${activeTabId}:${tabs.map((tab) => `${tab.id}:${tab.title || ''}`).join('|')}`
|
||||
|
||||
useLayoutEffect(() => {
|
||||
@ -429,6 +432,46 @@ const useActiveTabStickyScroll = (activeTabId, tabs) => {
|
||||
}
|
||||
}, [tabLayoutKey])
|
||||
|
||||
useEffect(() => {
|
||||
const lastTab = tabs[tabs.length - 1]
|
||||
if (
|
||||
tabs.length === prevTabCountRef.current + 1 &&
|
||||
lastTab?.id === activeTabId
|
||||
) {
|
||||
pendingScrollTabIdRef.current = lastTab.id
|
||||
}
|
||||
prevTabCountRef.current = tabs.length
|
||||
|
||||
if (!lastTab || pendingScrollTabIdRef.current !== lastTab.id) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const list = listRef.current
|
||||
const scrollEl = rootRef.current?.querySelector(
|
||||
'.simplebar-content-wrapper'
|
||||
)
|
||||
const outlineEl = list?.lastElementChild?.querySelector(
|
||||
'.dashboard-tab-item-outline-container'
|
||||
)
|
||||
if (!scrollEl || !outlineEl) return undefined
|
||||
|
||||
const scrollToEndIfReady = () => {
|
||||
if (outlineEl.getBoundingClientRect().width <= 36) return false
|
||||
scrollEl.scrollLeft = scrollEl.scrollWidth
|
||||
pendingScrollTabIdRef.current = null
|
||||
return true
|
||||
}
|
||||
|
||||
if (scrollToEndIfReady()) return undefined
|
||||
|
||||
const observer = new ResizeObserver(() => {
|
||||
if (scrollToEndIfReady()) observer.disconnect()
|
||||
})
|
||||
observer.observe(outlineEl)
|
||||
|
||||
return () => observer.disconnect()
|
||||
}, [activeTabId, tabs])
|
||||
|
||||
return { rootRef, listRef, cloneRef, lineRef }
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user