Remove all styled(Component) patterns in favor of parent wrappers and props (#18430)

## Summary

Eliminates all ~350 `styled(Component)` usages across `twenty-front` and
`twenty-ui` (212 files changed). Each was replaced following these
rules:

- **Margin/layout CSS** (margin, padding, flex, align-self, width) →
wrapped in a `styled.div`/`styled.span` parent container
- **Third-party components** (Link, TextareaAutosize,
ReactPhoneNumberInput, Handle, etc.) → parent container with child CSS
selectors (`> a`, `> textarea`, `> input`, etc.)
- **Intrinsic behavior via existing props** (TableRow
`gridTemplateColumns`, TableCell `color`/`align`) → replaced
`styled(TableRow)` / `styled(TableCell)` with direct prop usage
- **Other visual overrides on twenty-ui components** (Card, Section,
TabList, Button, MenuItem, ScrollWrapper, etc.) → parent wrappers with
`> div` / `> *` child selectors
- **Extending styled.div/span** → merged all CSS into a single
`styled.div`/`styled.span`

Also adds `overflow: hidden` to parent containers wrapping
`ScrollWrapper` so scroll activates correctly with the new wrapper
structure.

### Migration patterns

| Before | After |
|--------|-------|
| `styled(Avatar)` with `margin-right` | `<StyledAvatarContainer><Avatar
/></StyledAvatarContainer>` |
| `styled(Link)` with `text-decoration: none` |
`<StyledLinkContainer><Link /></StyledLinkContainer>` with `> a { ... }`
|
| `styled(TableRow)` with `grid-template-columns` | `<TableRow
gridTemplateColumns="..." />` |
| `styled(TableCell)` with `color` / `align` | `<TableCell color={...}
align="right" />` |
| `styled(Card)` with `margin-top` | `<StyledCardContainer><Card
/></StyledCardContainer>` |
| `styled(TabList)` with `background` |
`<StyledTabListContainer><TabList /></StyledTabListContainer>` with `>
div { ... }` |
| `styled(StyledBase)` extending a `styled.div` | Single merged
`styled.div` with all styles inlined |
This commit is contained in:
Charles Bochet
2026-03-05 18:16:25 +01:00
committed by GitHub
parent e5e3132ddd
commit c53a13417e
224 changed files with 4765 additions and 3837 deletions
@@ -6,23 +6,10 @@ import { StyledTableRow } from '@/settings/logic-functions/components/SettingsLo
import { useContext } from 'react';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
const StyledNameTableCell = styled(TableCell)`
color: ${themeCssVariables.font.color.primary};
gap: ${themeCssVariables.spacing[2]};
`;
const StyledRuntimeTableCell = styled(TableCell)`
color: ${themeCssVariables.font.color.secondary};
gap: ${themeCssVariables.spacing[2]};
`;
const StyledIconTableCell = styled(TableCell)`
justify-content: center;
padding-right: ${themeCssVariables.spacing[1]};
`;
const StyledIconChevronRight = styled(IconChevronRight)`
const StyledIconChevronRightContainer = styled.span`
align-items: center;
color: ${themeCssVariables.font.color.tertiary};
display: flex;
`;
export const SettingsLogicFunctionsFieldItemTableRow = ({
@@ -35,15 +22,33 @@ export const SettingsLogicFunctionsFieldItemTableRow = ({
const { theme } = useContext(ThemeContext);
return (
<StyledTableRow to={to}>
<StyledNameTableCell>{logicFunction.name}</StyledNameTableCell>
<StyledNameTableCell></StyledNameTableCell>
<StyledRuntimeTableCell>{logicFunction.runtime}</StyledRuntimeTableCell>
<StyledIconTableCell>
<StyledIconChevronRight
size={theme.icon.size.md}
stroke={theme.icon.stroke.sm}
/>
</StyledIconTableCell>
<TableCell
color={themeCssVariables.font.color.primary}
gap={themeCssVariables.spacing[2]}
>
{logicFunction.name}
</TableCell>
<TableCell
color={themeCssVariables.font.color.primary}
gap={themeCssVariables.spacing[2]}
></TableCell>
<TableCell
color={themeCssVariables.font.color.secondary}
gap={themeCssVariables.spacing[2]}
>
{logicFunction.runtime}
</TableCell>
<TableCell
align="center"
padding={`0 ${themeCssVariables.spacing[1]} 0 ${themeCssVariables.spacing[2]}`}
>
<StyledIconChevronRightContainer>
<IconChevronRight
size={theme.icon.size.md}
stroke={theme.icon.stroke.sm}
/>
</StyledIconChevronRightContainer>
</TableCell>
</StyledTableRow>
);
};
@@ -8,14 +8,21 @@ import { SettingsPath } from 'twenty-shared/types';
import { getSettingsPath } from 'twenty-shared/utils';
import { type LogicFunction } from '~/generated-metadata/graphql';
import { useLingui } from '@lingui/react/macro';
import React from 'react';
import { useParams } from 'react-router-dom';
import { themeCssVariables } from 'twenty-ui/theme-constants';
export const StyledTableRow = styled(TableRow)`
grid-template-columns: 164px 1fr 96px 32px;
`;
export const StyledTableRow = (
props: React.ComponentProps<typeof TableRow>,
) => (
<TableRow
gridTemplateColumns="164px 1fr 96px 32px"
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
/>
);
const StyledTableBody = styled(TableBody)`
const StyledTableBodyContainer = styled.div`
border-bottom: 1px solid ${themeCssVariables.border.color.light};
`;
@@ -40,18 +47,20 @@ export const SettingsLogicFunctionsTable = ({
<TableHeader>{t`Runtime`}</TableHeader>
<TableHeader></TableHeader>
</StyledTableRow>
<StyledTableBody>
{logicFunctions.map((logicFunction: LogicFunction) => (
<SettingsLogicFunctionsFieldItemTableRow
key={logicFunction.id}
logicFunction={logicFunction}
to={getSettingsPath(SettingsPath.ApplicationLogicFunctionDetail, {
applicationId,
logicFunctionId: logicFunction.id,
})}
/>
))}
</StyledTableBody>
<StyledTableBodyContainer>
<TableBody>
{logicFunctions.map((logicFunction: LogicFunction) => (
<SettingsLogicFunctionsFieldItemTableRow
key={logicFunction.id}
logicFunction={logicFunction}
to={getSettingsPath(SettingsPath.ApplicationLogicFunctionDetail, {
applicationId,
logicFunctionId: logicFunction.id,
})}
/>
))}
</TableBody>
</StyledTableBodyContainer>
</Table>
);
};
@@ -12,8 +12,10 @@ import { H2Title, IconPlayerPlay } from 'twenty-ui/display';
import { Button, CoreEditorHeader } from 'twenty-ui/input';
import { Section } from 'twenty-ui/layout';
const StyledTabList = styled(TabList)`
border-bottom: none;
const StyledTabListContainer = styled.div`
> * {
border-bottom: none;
}
`;
export const SettingsLogicFunctionCodeEditorTab = ({
@@ -44,12 +46,14 @@ export const SettingsLogicFunctionCodeEditorTab = ({
);
const HeaderTabList = (
<StyledTabList
tabs={files.map((file) => {
return { id: file.path, title: file.path.split('/').at(-1) || '' };
})}
componentInstanceId={SETTINGS_LOGIC_FUNCTION_TAB_LIST_COMPONENT_ID}
/>
<StyledTabListContainer>
<TabList
tabs={files.map((file) => {
return { id: file.path, title: file.path.split('/').at(-1) || '' };
})}
componentInstanceId={SETTINGS_LOGIC_FUNCTION_TAB_LIST_COMPONENT_ID}
/>
</StyledTabListContainer>
);
return (
@@ -5,9 +5,8 @@ import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/Drop
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { TableCell } from '@/ui/layout/table/components/TableCell';
import { TableRow } from '@/ui/layout/table/components/TableRow';
import { styled } from '@linaria/react';
import { t } from '@lingui/core/macro';
import { useState } from 'react';
import React, { useState } from 'react';
import {
IconCheck,
IconDotsVertical,
@@ -20,13 +19,23 @@ import { LightIconButton } from 'twenty-ui/input';
import { MenuItem } from 'twenty-ui/navigation';
import type { ApplicationVariable } from '~/generated-metadata/graphql';
const StyledEditModeTableRow = styled(TableRow)`
grid-template-columns: 180px auto 56px;
`;
const StyledEditModeTableRow = (
props: React.ComponentProps<typeof TableRow>,
) => (
<TableRow
gridTemplateColumns="180px auto 56px"
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
/>
);
const StyledTableRow = styled(TableRow)`
grid-template-columns: 180px 300px 32px;
`;
const StyledTableRow = (props: React.ComponentProps<typeof TableRow>) => (
<TableRow
gridTemplateColumns="180px 300px 32px"
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
/>
);
export const SettingsLogicFunctionTabEnvironmentVariableTableRow = ({
envVariable,
@@ -14,18 +14,9 @@ import { Tag } from 'twenty-ui/components';
import { type LogicFunction } from '~/generated-metadata/graphql';
import { themeCssVariables } from 'twenty-ui/theme-constants';
export const StyledRouteTriggerTableRow = styled(TableRow)`
grid-template-columns: 1fr 120px 120px;
`;
const ROUTE_TRIGGER_GRID_TEMPLATE_COLUMNS = '1fr 120px 120px';
const StyledTableCell = styled(TableCell)`
color: ${themeCssVariables.font.color.tertiary};
gap: ${themeCssVariables.spacing[2]};
min-width: 0;
overflow: hidden;
`;
const StyledRouteTriggerTableHeaderRow = styled(StyledRouteTriggerTableRow)`
const StyledRouteTriggerTableHeaderRowWrapper = styled.div`
margin-bottom: ${themeCssVariables.spacing[2]};
`;
@@ -119,26 +110,44 @@ export const SettingsLogicFunctionTriggersTab = ({
description={t`Triggers the function with Http request`}
/>
<Table>
<StyledRouteTriggerTableHeaderRow>
<TableHeader>{t`Path`}</TableHeader>
<TableHeader>{t`Method`}</TableHeader>
<TableHeader>{t`Auth Required`}</TableHeader>
</StyledRouteTriggerTableHeaderRow>
<StyledRouteTriggerTableRow>
<StyledTableCell>
<StyledRouteTriggerTableHeaderRowWrapper>
<TableRow
gridTemplateColumns={ROUTE_TRIGGER_GRID_TEMPLATE_COLUMNS}
>
<TableHeader>{t`Path`}</TableHeader>
<TableHeader>{t`Method`}</TableHeader>
<TableHeader>{t`Auth Required`}</TableHeader>
</TableRow>
</StyledRouteTriggerTableHeaderRowWrapper>
<TableRow gridTemplateColumns={ROUTE_TRIGGER_GRID_TEMPLATE_COLUMNS}>
<TableCell
color={themeCssVariables.font.color.tertiary}
gap={themeCssVariables.spacing[2]}
overflow="hidden"
>
<OverflowingTextWithTooltip
text={`${REACT_APP_SERVER_BASE_URL}/s${routeTrigger.path}`}
/>
</StyledTableCell>
<StyledTableCell>{routeTrigger.httpMethod}</StyledTableCell>
<StyledTableCell>
</TableCell>
<TableCell
color={themeCssVariables.font.color.tertiary}
gap={themeCssVariables.spacing[2]}
overflow="hidden"
>
{routeTrigger.httpMethod}
</TableCell>
<TableCell
color={themeCssVariables.font.color.tertiary}
gap={themeCssVariables.spacing[2]}
overflow="hidden"
>
<Tag
text={routeTrigger.isAuthRequired ? t`True` : t`False`}
color={routeTrigger.isAuthRequired ? 'green' : 'orange'}
weight="medium"
/>
</StyledTableCell>
</StyledRouteTriggerTableRow>
</TableCell>
</TableRow>
</Table>
</Section>
)}