From 5a991feed69e2e5f5cabd04230497d508ba15f50 Mon Sep 17 00:00:00 2001 From: Michael Sun <55160142+MichaelSun48@users.noreply.github.com> Date: Tue, 17 Sep 2024 15:02:12 -0700 Subject: [PATCH] fix(custom-views): TabDivider improvements, other style changes (#77661) Various cosmetic improvements to custom views: 1. Tab dividers now disappear when hovering around the add view button 2. tab dividers disappear correctly when a temp tab is active 3. The add view button has been given some more left/right padding since it looked very cramped before 4. The logic to decide whether or not a tab divider should be shown is more readable now. --- .../draggableTabs/draggableTabList.tsx | 110 ++++++++++++++---- 1 file changed, 85 insertions(+), 25 deletions(-) diff --git a/static/app/components/draggableTabs/draggableTabList.tsx b/static/app/components/draggableTabs/draggableTabList.tsx index d3a7aa82d9617b..7ee03e4a427b9c 100644 --- a/static/app/components/draggableTabs/draggableTabList.tsx +++ b/static/app/components/draggableTabs/draggableTabList.tsx @@ -127,14 +127,20 @@ function Tabs({ setTabRefs, tabs, overflowingTabs, + hoveringKey, + setHoveringKey, + tempTabActive, }: { ariaProps: AriaTabListOptions; + hoveringKey: Key | 'addView' | null; onReorder: (newOrder: Node[]) => void; orientation: 'horizontal' | 'vertical'; overflowingTabs: Node[]; + setHoveringKey: (key: Key | 'addView' | null) => void; setTabRefs: Dispatch>>; state: TabListState; tabs: Node[]; + tempTabActive: boolean; className?: string; disabled?: boolean; onChange?: (key: string | number) => void; @@ -147,12 +153,49 @@ function Tabs({ const values = useMemo(() => [...state.collection], [state.collection]); const [isDragging, setIsDragging] = useState(false); - const [hoveringKey, setHoveringKey] = useState(null); // Only apply this while dragging, because it causes tabs to stay within the container // which we do not want (we hide tabs once they overflow const dragConstraints = isDragging ? tabListRef : undefined; + const isTabDividerVisible = tabKey => { + // If the tab divider is succeeding or preceding the selected tab key + if ( + state.selectedKey === tabKey || + (state.selectedKey !== TEMPORARY_TAB_KEY && + state.collection.getKeyAfter(tabKey) !== TEMPORARY_TAB_KEY && + state.collection.getKeyAfter(tabKey) === state.selectedKey) + ) { + return false; + } + + // If the tab divider is succeeding or preceding the hovering tab key + if ( + hoveringKey !== TEMPORARY_TAB_KEY && + (hoveringKey === tabKey || hoveringKey === state.collection.getKeyAfter(tabKey)) + ) { + return false; + } + + if ( + tempTabActive && + state.collection.getKeyAfter(tabKey) === TEMPORARY_TAB_KEY && + hoveringKey === 'addView' + ) { + return false; + } + + if ( + tabKey !== TEMPORARY_TAB_KEY && + !state.collection.getKeyAfter(tabKey) && + hoveringKey === 'addView' + ) { + return false; + } + + return true; + }; + return ( - + ))} @@ -226,6 +260,7 @@ function BaseDraggableTabList({ tabVariant = 'filled', ...props }: BaseDraggableTabListProps) { + const [hoveringKey, setHoveringKey] = useState(null); const {rootProps, setTabListState} = useContext(TabsContext); const { value, @@ -285,25 +320,44 @@ function BaseDraggableTabList({ setTabRefs={setTabElements} tabs={persistentTabs} overflowingTabs={overflowingTabs} + hoveringKey={hoveringKey} + setHoveringKey={setHoveringKey} + tempTabActive={!!tempTab} /> - + setHoveringKey('addView')} + onHoverEnd={() => setHoveringKey(null)} + > {t('Add View')} - + + setHoveringKey(TEMPORARY_TAB_KEY)} + onHoverEnd={() => setHoveringKey(null)} + > {tempTab && ( - + + + )} {overflowingTabs.length > 0 ? ( @@ -371,6 +425,12 @@ const TabItemWrap = styled(Reorder.Item, { z-index: ${p => (p.isSelected ? 1 : 0)}; `; +const TempTabWrap = styled('div')` + display: flex; + position: relative; + line-height: 1.6; +`; + /** * TabDividers are only visible around NON-selected tabs. They are not visible around the selected tab, * but they still create some space and act as a gap between tabs. @@ -413,7 +473,6 @@ const AddViewTempTabWrap = styled('div')` grid-auto-flow: column; justify-content: start; align-items: center; - top: -1px; `; const TabListWrap = styled('ul')` @@ -435,8 +494,8 @@ const AddViewButton = styled(Button)` display: flex; color: ${p => p.theme.gray300}; font-weight: normal; - padding: ${space(0.5)}; - margin-right: ${space(0.5)}; + padding: ${space(0.5)} ${space(1)}; + margin-bottom: 1px; border: none; bottom: -1px; `; @@ -448,6 +507,7 @@ const StyledIconAdd = styled(IconAdd)` const MotionWrapper = styled(motion.div)` display: flex; position: relative; + bottom: 1px; `; const AddViewMotionWrapper = styled(motion.div)`