Tablist bottom margin fix (#10801)

### Bug
The active tab bottom border appeared slightly above the TabList's light
bottom border.

### Investigation
- Initial fix: Adjusted margin-bottom to -1px in Tab component to align
borders
- This fix caused active bottom borders to disappear in tabs wrapped
with ShowPageSubContainerTabListContainer
- Found that ShowPageSubContainerTabListContainer was adding a redundant
bottom border that overlapped with TabList's border

### Solution
- Removed ShowPageSubContainerTabListContainer to eliminate the
redundant border
- Kept the -1px margin-bottom fix in Tab component
- This ensures consistent border behavior across all TabList
implementations
This commit is contained in:
nitin
2025-03-12 19:15:50 +05:30
committed by GitHub
parent 6102277de6
commit 5ddc34b182
7 changed files with 29 additions and 45 deletions

View File

@ -1,4 +1,3 @@
import { ShowPageSubContainerTabListContainer } from '@/ui/layout/show-page/components/ShowPageSubContainerTabListContainer';
import { SingleTabProps, TabList } from '@/ui/layout/tab/components/TabList'; import { SingleTabProps, TabList } from '@/ui/layout/tab/components/TabList';
import { useTabList } from '@/ui/layout/tab/hooks/useTabList'; import { useTabList } from '@/ui/layout/tab/hooks/useTabList';
import { useFlowOrThrow } from '@/workflow/hooks/useFlowOrThrow'; import { useFlowOrThrow } from '@/workflow/hooks/useFlowOrThrow';
@ -16,8 +15,9 @@ import styled from '@emotion/styled';
import { isDefined } from 'twenty-shared'; import { isDefined } from 'twenty-shared';
import { IconLogin2, IconLogout, IconStepInto } from 'twenty-ui'; import { IconLogin2, IconLogout, IconStepInto } from 'twenty-ui';
const StyledTabListContainer = styled(ShowPageSubContainerTabListContainer)` const StyledTabList = styled(TabList)`
background-color: ${({ theme }) => theme.background.secondary}; background-color: ${({ theme }) => theme.background.secondary};
padding-left: ${({ theme }) => theme.spacing(2)};
`; `;
type TabId = 'node' | 'input' | 'output'; type TabId = 'node' | 'input' | 'output';
@ -69,13 +69,11 @@ export const CommandMenuWorkflowRunViewStep = () => {
<WorkflowStepContextProvider <WorkflowStepContextProvider
value={{ workflowVersionId: workflowRun.workflowVersionId }} value={{ workflowVersionId: workflowRun.workflowVersionId }}
> >
<StyledTabListContainer> <StyledTabList
<TabList tabListInstanceId={WORKFLOW_RUN_STEP_SIDE_PANEL_TAB_LIST_COMPONENT_ID}
tabListInstanceId={WORKFLOW_RUN_STEP_SIDE_PANEL_TAB_LIST_COMPONENT_ID} tabs={tabs}
tabs={tabs} behaveAsLinks={false}
behaveAsLinks={false} />
/>
</StyledTabListContainer>
{activeTabId === 'node' ? ( {activeTabId === 'node' ? (
<WorkflowStepDetail <WorkflowStepDetail

View File

@ -10,7 +10,6 @@ import { recordStoreFamilyState } from '@/object-record/record-store/states/reco
import { ObjectRecord } from '@/object-record/types/ObjectRecord'; import { ObjectRecord } from '@/object-record/types/ObjectRecord';
import { RightDrawerFooter } from '@/ui/layout/right-drawer/components/RightDrawerFooter'; import { RightDrawerFooter } from '@/ui/layout/right-drawer/components/RightDrawerFooter';
import { ShowPageLeftContainer } from '@/ui/layout/show-page/components/ShowPageLeftContainer'; import { ShowPageLeftContainer } from '@/ui/layout/show-page/components/ShowPageLeftContainer';
import { ShowPageSubContainerTabListContainer } from '@/ui/layout/show-page/components/ShowPageSubContainerTabListContainer';
import { SingleTabProps, TabList } from '@/ui/layout/tab/components/TabList'; import { SingleTabProps, TabList } from '@/ui/layout/tab/components/TabList';
import { useTabList } from '@/ui/layout/tab/hooks/useTabList'; import { useTabList } from '@/ui/layout/tab/hooks/useTabList';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile'; import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
@ -29,7 +28,11 @@ const StyledShowPageRightContainer = styled.div<{ isMobile: boolean }>`
const StyledTabListContainer = styled.div<{ shouldDisplay: boolean }>` const StyledTabListContainer = styled.div<{ shouldDisplay: boolean }>`
display: ${({ shouldDisplay }) => (shouldDisplay ? 'flex' : 'none')}; display: ${({ shouldDisplay }) => (shouldDisplay ? 'flex' : 'none')};
`.withComponent(ShowPageSubContainerTabListContainer); `;
const StyledTabList = styled(TabList)`
padding-left: ${({ theme }) => theme.spacing(2)};
`;
const StyledContentContainer = styled.div<{ isInRightDrawer: boolean }>` const StyledContentContainer = styled.div<{ isInRightDrawer: boolean }>`
flex: 1; flex: 1;
@ -122,7 +125,7 @@ export const ShowPageSubContainer = ({
)} )}
<StyledShowPageRightContainer isMobile={isMobile}> <StyledShowPageRightContainer isMobile={isMobile}>
<StyledTabListContainer shouldDisplay={visibleTabs.length > 1}> <StyledTabListContainer shouldDisplay={visibleTabs.length > 1}>
<TabList <StyledTabList
behaveAsLinks={!isInRightDrawer} behaveAsLinks={!isInRightDrawer}
loading={loading || isNewViewableRecordLoading} loading={loading || isNewViewableRecordLoading}
tabListInstanceId={tabListComponentId} tabListInstanceId={tabListComponentId}

View File

@ -1,13 +0,0 @@
import styled from '@emotion/styled';
const StyledTabListContainer = styled.div`
align-items: center;
padding-left: ${({ theme }) => theme.spacing(2)};
border-bottom: ${({ theme }) => `1px solid ${theme.border.color.light}`};
box-sizing: border-box;
display: flex;
gap: ${({ theme }) => theme.spacing(2)};
height: 40px;
`;
export { StyledTabListContainer as ShowPageSubContainerTabListContainer };

View File

@ -41,7 +41,7 @@ const StyledTab = styled('button', {
display: flex; display: flex;
gap: ${({ theme }) => theme.spacing(1)}; gap: ${({ theme }) => theme.spacing(1)};
justify-content: center; justify-content: center;
margin-bottom: 0; margin-bottom: -1px;
padding: ${({ theme }) => theme.spacing(2) + ' 0'}; padding: ${({ theme }) => theme.spacing(2) + ' 0'};
pointer-events: ${({ disabled }) => (disabled ? 'none' : '')}; pointer-events: ${({ disabled }) => (disabled ? 'none' : '')};
text-decoration: none; text-decoration: none;

View File

@ -33,7 +33,7 @@ const StyledContainer = styled.div`
border-bottom: ${({ theme }) => `1px solid ${theme.border.color.light}`}; border-bottom: ${({ theme }) => `1px solid ${theme.border.color.light}`};
box-sizing: border-box; box-sizing: border-box;
display: flex; display: flex;
gap: ${({ theme }) => theme.spacing(2)}; gap: ${({ theme }) => theme.spacing(1)};
height: 40px; height: 40px;
user-select: none; user-select: none;
`; `;

View File

@ -1,4 +1,3 @@
import { ShowPageSubContainerTabListContainer } from '@/ui/layout/show-page/components/ShowPageSubContainerTabListContainer';
import { SingleTabProps, TabList } from '@/ui/layout/tab/components/TabList'; import { SingleTabProps, TabList } from '@/ui/layout/tab/components/TabList';
import { useTabList } from '@/ui/layout/tab/hooks/useTabList'; import { useTabList } from '@/ui/layout/tab/hooks/useTabList';
import { useFlowOrThrow } from '@/workflow/hooks/useFlowOrThrow'; import { useFlowOrThrow } from '@/workflow/hooks/useFlowOrThrow';
@ -16,8 +15,9 @@ import styled from '@emotion/styled';
import { isDefined } from 'twenty-shared'; import { isDefined } from 'twenty-shared';
import { IconLogin2, IconLogout, IconStepInto } from 'twenty-ui'; import { IconLogin2, IconLogout, IconStepInto } from 'twenty-ui';
const StyledTabListContainer = styled(ShowPageSubContainerTabListContainer)` const StyledTabList = styled(TabList)`
background-color: ${({ theme }) => theme.background.secondary}; background-color: ${({ theme }) => theme.background.secondary};
padding-left: ${({ theme }) => theme.spacing(2)};
`; `;
type TabId = 'node' | 'input' | 'output'; type TabId = 'node' | 'input' | 'output';
@ -69,13 +69,11 @@ export const RightDrawerWorkflowRunViewStep = () => {
<WorkflowStepContextProvider <WorkflowStepContextProvider
value={{ workflowVersionId: flow.workflowVersionId }} value={{ workflowVersionId: flow.workflowVersionId }}
> >
<StyledTabListContainer> <StyledTabList
<TabList tabListInstanceId={WORKFLOW_RUN_STEP_SIDE_PANEL_TAB_LIST_COMPONENT_ID}
tabListInstanceId={WORKFLOW_RUN_STEP_SIDE_PANEL_TAB_LIST_COMPONENT_ID} tabs={tabs}
tabs={tabs} behaveAsLinks={false}
behaveAsLinks={false} />
/>
</StyledTabListContainer>
{activeTabId === 'node' ? ( {activeTabId === 'node' ? (
<WorkflowStepDetail <WorkflowStepDetail

View File

@ -17,7 +17,6 @@ import { getFunctionOutputSchema } from '@/serverless-functions/utils/getFunctio
import { mergeDefaultFunctionInputAndFunctionInput } from '@/serverless-functions/utils/mergeDefaultFunctionInputAndFunctionInput'; import { mergeDefaultFunctionInputAndFunctionInput } from '@/serverless-functions/utils/mergeDefaultFunctionInputAndFunctionInput';
import { InputLabel } from '@/ui/input/components/InputLabel'; import { InputLabel } from '@/ui/input/components/InputLabel';
import { RightDrawerFooter } from '@/ui/layout/right-drawer/components/RightDrawerFooter'; import { RightDrawerFooter } from '@/ui/layout/right-drawer/components/RightDrawerFooter';
import { ShowPageSubContainerTabListContainer } from '@/ui/layout/show-page/components/ShowPageSubContainerTabListContainer';
import { TabList } from '@/ui/layout/tab/components/TabList'; import { TabList } from '@/ui/layout/tab/components/TabList';
import { useTabList } from '@/ui/layout/tab/hooks/useTabList'; import { useTabList } from '@/ui/layout/tab/hooks/useTabList';
import { serverlessFunctionTestDataFamilyState } from '@/workflow/states/serverlessFunctionTestDataFamilyState'; import { serverlessFunctionTestDataFamilyState } from '@/workflow/states/serverlessFunctionTestDataFamilyState';
@ -50,8 +49,9 @@ const StyledCodeEditorContainer = styled.div`
flex-direction: column; flex-direction: column;
`; `;
const StyledTabListContainer = styled(ShowPageSubContainerTabListContainer)` const StyledTabList = styled(TabList)`
background-color: ${({ theme }) => theme.background.secondary}; background-color: ${({ theme }) => theme.background.secondary};
padding-left: ${({ theme }) => theme.spacing(2)};
`; `;
type WorkflowEditActionFormServerlessFunctionProps = { type WorkflowEditActionFormServerlessFunctionProps = {
@ -285,13 +285,11 @@ export const WorkflowEditActionFormServerlessFunction = ({
return ( return (
!loading && ( !loading && (
<StyledContainer> <StyledContainer>
<StyledTabListContainer> <StyledTabList
<TabList tabListInstanceId={tabListId}
tabListInstanceId={tabListId} tabs={tabs}
tabs={tabs} behaveAsLinks={false}
behaveAsLinks={false} />
/>
</StyledTabListContainer>
<WorkflowStepHeader <WorkflowStepHeader
onTitleChange={(newName: string) => { onTitleChange={(newName: string) => {
updateAction({ name: newName }); updateAction({ name: newName });