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:
+10
-6
@@ -26,8 +26,10 @@ const StyledDotContainer = styled.div<{ dotPosition: DotPosition }>`
|
||||
dotPosition === 'top' ? 'stretch' : 'center'};
|
||||
`;
|
||||
|
||||
const StyledIconPoint = styled(IconPoint)`
|
||||
const StyledIconPointContainer = styled.span`
|
||||
margin-right: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
`;
|
||||
|
||||
export const AdvancedSettingsContentWrapperWithDot = ({
|
||||
@@ -41,11 +43,13 @@ export const AdvancedSettingsContentWrapperWithDot = ({
|
||||
<StyledWrapper>
|
||||
{!hideDot && (
|
||||
<StyledDotContainer dotPosition={dotPosition}>
|
||||
<StyledIconPoint
|
||||
size={12}
|
||||
color={theme.color.yellow}
|
||||
fill={theme.color.yellow}
|
||||
/>
|
||||
<StyledIconPointContainer>
|
||||
<IconPoint
|
||||
size={12}
|
||||
color={theme.color.yellow}
|
||||
fill={theme.color.yellow}
|
||||
/>
|
||||
</StyledIconPointContainer>
|
||||
</StyledDotContainer>
|
||||
)}
|
||||
{children}
|
||||
|
||||
@@ -18,28 +18,34 @@ type SettingsCardProps = {
|
||||
Status?: ReactNode;
|
||||
};
|
||||
|
||||
const StyledCard = styled(Card)<{
|
||||
const StyledCardWrapper = styled.div<{
|
||||
disabled?: boolean;
|
||||
onClick?: () => void;
|
||||
clickable?: boolean;
|
||||
}>`
|
||||
color: ${({ disabled }) =>
|
||||
disabled
|
||||
? themeCssVariables.font.color.extraLight
|
||||
: themeCssVariables.font.color.tertiary};
|
||||
cursor: ${({ disabled, onClick }) =>
|
||||
disabled ? 'not-allowed' : onClick ? 'pointer' : 'default'};
|
||||
cursor: ${({ disabled, clickable }) =>
|
||||
disabled ? 'not-allowed' : clickable ? 'pointer' : 'default'};
|
||||
width: 100%;
|
||||
|
||||
> * {
|
||||
color: inherit;
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledCardContent = styled(CardContent)`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
padding: ${themeCssVariables.spacing[2]} ${themeCssVariables.spacing[2]};
|
||||
const StyledCardContentContainer = styled.div`
|
||||
> * {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
padding: ${themeCssVariables.spacing[2]} ${themeCssVariables.spacing[2]};
|
||||
|
||||
&:hover {
|
||||
background-color: ${themeCssVariables.background.quaternary};
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background-color: ${themeCssVariables.background.quaternary};
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -61,8 +67,10 @@ const StyledTitle = styled.div<{ disabled?: boolean }>`
|
||||
justify-content: flex-start;
|
||||
`;
|
||||
|
||||
const StyledIconChevronRight = styled(IconChevronRight)`
|
||||
const StyledIconChevronRightContainer = styled.span`
|
||||
align-items: center;
|
||||
color: ${themeCssVariables.font.color.light};
|
||||
display: flex;
|
||||
`;
|
||||
|
||||
const StyledDescription = styled.div`
|
||||
@@ -91,24 +99,31 @@ export const SettingsCard = ({
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
return (
|
||||
<StyledCard
|
||||
<StyledCardWrapper
|
||||
disabled={disabled}
|
||||
onClick={disabled ? undefined : onClick}
|
||||
clickable={!!onClick}
|
||||
className={className}
|
||||
rounded={true}
|
||||
>
|
||||
<StyledCardContent>
|
||||
<StyledHeader>
|
||||
<StyledIconContainer>{Icon}</StyledIconContainer>
|
||||
<StyledTitle disabled={disabled}>
|
||||
{title}
|
||||
{soon && <Pill label={t`Soon`} />}
|
||||
</StyledTitle>
|
||||
{Status && Status}
|
||||
<StyledIconChevronRight size={theme.icon.size.sm} />
|
||||
</StyledHeader>
|
||||
{description && <StyledDescription>{description}</StyledDescription>}
|
||||
</StyledCardContent>
|
||||
</StyledCard>
|
||||
<Card onClick={disabled ? undefined : onClick} rounded={true} fullWidth>
|
||||
<StyledCardContentContainer>
|
||||
<CardContent>
|
||||
<StyledHeader>
|
||||
<StyledIconContainer>{Icon}</StyledIconContainer>
|
||||
<StyledTitle disabled={disabled}>
|
||||
{title}
|
||||
{soon && <Pill label={t`Soon`} />}
|
||||
</StyledTitle>
|
||||
{Status && Status}
|
||||
<StyledIconChevronRightContainer>
|
||||
<IconChevronRight size={theme.icon.size.sm} />
|
||||
</StyledIconChevronRightContainer>
|
||||
</StyledHeader>
|
||||
{description && (
|
||||
<StyledDescription>{description}</StyledDescription>
|
||||
)}
|
||||
</CardContent>
|
||||
</StyledCardContentContainer>
|
||||
</Card>
|
||||
</StyledCardWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
+23
-17
@@ -14,10 +14,12 @@ const StyledNameCell = styled.div`
|
||||
gap: ${themeCssVariables.spacing[1]};
|
||||
`;
|
||||
|
||||
const StyledTableRow = styled(TableRow)`
|
||||
&:hover {
|
||||
background: ${themeCssVariables.background.transparent.light};
|
||||
cursor: pointer;
|
||||
const StyledTableRowContainer = styled.div`
|
||||
> * {
|
||||
&:hover {
|
||||
background-color: ${themeCssVariables.background.transparent.light};
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -32,19 +34,23 @@ export const SettingsConnectedAccountsTableRow = ({
|
||||
const IconComponent = SettingsConnectedAccountIcon({ account });
|
||||
|
||||
return (
|
||||
<StyledTableRow key={account.id} gridAutoColumns="332px 1fr">
|
||||
<TableCell>
|
||||
<StyledNameCell>
|
||||
<IconComponent
|
||||
size={theme.icon.size.md}
|
||||
stroke={theme.icon.stroke.sm}
|
||||
<StyledTableRowContainer>
|
||||
<TableRow key={account.id} gridAutoColumns="332px 1fr">
|
||||
<TableCell>
|
||||
<StyledNameCell>
|
||||
<IconComponent
|
||||
size={theme.icon.size.md}
|
||||
stroke={theme.icon.stroke.sm}
|
||||
/>
|
||||
{account.handle}
|
||||
</StyledNameCell>
|
||||
</TableCell>
|
||||
<TableCell align="right">
|
||||
<SettingsAccountsConnectedAccountsRowRightContainer
|
||||
account={account}
|
||||
/>
|
||||
{account.handle}
|
||||
</StyledNameCell>
|
||||
</TableCell>
|
||||
<TableCell align="right">
|
||||
<SettingsAccountsConnectedAccountsRowRightContainer account={account} />
|
||||
</TableCell>
|
||||
</StyledTableRow>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</StyledTableRowContainer>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -25,9 +25,10 @@ const StyledCounterContainer = styled.div<{ showButtons: boolean }>`
|
||||
: themeCssVariables.spacing[16]};
|
||||
`;
|
||||
|
||||
const StyledTextInput = styled(SettingsTextInput)`
|
||||
const StyledTextInputContainer = styled.div`
|
||||
width: ${themeCssVariables.spacing[16]};
|
||||
input {
|
||||
|
||||
> * input {
|
||||
width: ${themeCssVariables.spacing[16]};
|
||||
height: ${themeCssVariables.spacing[6]};
|
||||
text-align: center;
|
||||
@@ -84,14 +85,16 @@ export const SettingsCounter = ({
|
||||
disabled={disabled}
|
||||
/>
|
||||
)}
|
||||
<StyledTextInput
|
||||
instanceId="settings-counter-input"
|
||||
name="counter"
|
||||
fullWidth
|
||||
value={value.toString()}
|
||||
onChange={handleTextInputChange}
|
||||
disabled={disabled}
|
||||
/>
|
||||
<StyledTextInputContainer>
|
||||
<SettingsTextInput
|
||||
instanceId="settings-counter-input"
|
||||
name="counter"
|
||||
fullWidth
|
||||
value={value.toString()}
|
||||
onChange={handleTextInputChange}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</StyledTextInputContainer>
|
||||
{showButtons && (
|
||||
<IconButton
|
||||
size="small"
|
||||
|
||||
@@ -28,15 +28,16 @@ type SettingsDnsRecordsTableProps = {
|
||||
records: DnsRecord[];
|
||||
};
|
||||
|
||||
const StyledTableRow = styled(TableRow)`
|
||||
& > * {
|
||||
const StyledTableRowContainer = styled.div`
|
||||
> * > * {
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledTableCell = styled(TableCell)`
|
||||
const StyledTableCellFontWrapper = styled.div`
|
||||
display: contents;
|
||||
font-family: monospace;
|
||||
`;
|
||||
|
||||
@@ -69,53 +70,69 @@ export const SettingsDnsRecordsTable = ({
|
||||
|
||||
return (
|
||||
<Table>
|
||||
<StyledTableRow gridAutoColumns={gridAutoColumns}>
|
||||
<TableHeader align="center">{t`Type`}</TableHeader>
|
||||
<TableHeader align="center">{t`Key`}</TableHeader>
|
||||
<TableHeader align="center">{t`Value`}</TableHeader>
|
||||
{hasPriorityRecords && (
|
||||
<TableHeader align="center">{t`Priority`}</TableHeader>
|
||||
)}
|
||||
{hasTtlRecords && <TableHeader align="center">{t`TTL`}</TableHeader>}
|
||||
{hasStatusRecords && (
|
||||
<TableHeader align="center">{t`Status`}</TableHeader>
|
||||
)}
|
||||
</StyledTableRow>
|
||||
<StyledTableRowContainer>
|
||||
<TableRow gridAutoColumns={gridAutoColumns}>
|
||||
<TableHeader align="center">{t`Type`}</TableHeader>
|
||||
<TableHeader align="center">{t`Key`}</TableHeader>
|
||||
<TableHeader align="center">{t`Value`}</TableHeader>
|
||||
{hasPriorityRecords && (
|
||||
<TableHeader align="center">{t`Priority`}</TableHeader>
|
||||
)}
|
||||
{hasTtlRecords && <TableHeader align="center">{t`TTL`}</TableHeader>}
|
||||
{hasStatusRecords && (
|
||||
<TableHeader align="center">{t`Status`}</TableHeader>
|
||||
)}
|
||||
</TableRow>
|
||||
</StyledTableRowContainer>
|
||||
|
||||
{records.map((record) => (
|
||||
<StyledTableRow key={record.value} gridAutoColumns={gridAutoColumns}>
|
||||
<TableCell>{record.type}</TableCell>
|
||||
<StyledTableCell
|
||||
onClick={() => {
|
||||
copyToClipboard(record.key || '');
|
||||
}}
|
||||
>
|
||||
<OverflowingTextWithTooltip text={record.key} />
|
||||
</StyledTableCell>
|
||||
<StyledTableRowContainer key={record.value}>
|
||||
<TableRow gridAutoColumns={gridAutoColumns}>
|
||||
<TableCell>{record.type}</TableCell>
|
||||
<StyledTableCellFontWrapper>
|
||||
<TableCell
|
||||
onClick={() => {
|
||||
copyToClipboard(record.key || '');
|
||||
}}
|
||||
>
|
||||
<OverflowingTextWithTooltip text={record.key} />
|
||||
</TableCell>
|
||||
</StyledTableCellFontWrapper>
|
||||
|
||||
<StyledTableCell
|
||||
onClick={() => {
|
||||
copyToClipboard(record.value);
|
||||
}}
|
||||
>
|
||||
<OverflowingTextWithTooltip text={record.value} />
|
||||
</StyledTableCell>
|
||||
<StyledTableCellFontWrapper>
|
||||
<TableCell
|
||||
onClick={() => {
|
||||
copyToClipboard(record.value);
|
||||
}}
|
||||
>
|
||||
<OverflowingTextWithTooltip text={record.value} />
|
||||
</TableCell>
|
||||
</StyledTableCellFontWrapper>
|
||||
|
||||
{hasPriorityRecords && (
|
||||
<StyledTableCell>{record.priority}</StyledTableCell>
|
||||
)}
|
||||
{hasTtlRecords && <StyledTableCell>{record.ttl}</StyledTableCell>}
|
||||
{hasStatusRecords && (
|
||||
<StyledTableCell>
|
||||
{'status' in record ? (
|
||||
<Status
|
||||
color={record.statusColor}
|
||||
text={capitalize(record.status)}
|
||||
/>
|
||||
) : null}
|
||||
</StyledTableCell>
|
||||
)}
|
||||
</StyledTableRow>
|
||||
{hasPriorityRecords && (
|
||||
<StyledTableCellFontWrapper>
|
||||
<TableCell>{record.priority}</TableCell>
|
||||
</StyledTableCellFontWrapper>
|
||||
)}
|
||||
{hasTtlRecords && (
|
||||
<StyledTableCellFontWrapper>
|
||||
<TableCell>{record.ttl}</TableCell>
|
||||
</StyledTableCellFontWrapper>
|
||||
)}
|
||||
{hasStatusRecords && (
|
||||
<StyledTableCellFontWrapper>
|
||||
<TableCell>
|
||||
{'status' in record ? (
|
||||
<Status
|
||||
color={record.statusColor}
|
||||
text={capitalize(record.status)}
|
||||
/>
|
||||
) : null}
|
||||
</TableCell>
|
||||
</StyledTableCellFontWrapper>
|
||||
)}
|
||||
</TableRow>
|
||||
</StyledTableRowContainer>
|
||||
))}
|
||||
</Table>
|
||||
);
|
||||
|
||||
@@ -8,10 +8,12 @@ import { Card, CardFooter } from 'twenty-ui/layout';
|
||||
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import { SettingsListItemCardContent } from './SettingsListItemCardContent';
|
||||
|
||||
const StyledFooter = styled(CardFooter)`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
padding: ${themeCssVariables.spacing[1]};
|
||||
const StyledFooterContainer = styled.div`
|
||||
> * {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
padding: ${themeCssVariables.spacing[1]};
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledButton = styled.button`
|
||||
@@ -91,12 +93,14 @@ export const SettingsListCard = <
|
||||
/>
|
||||
))}
|
||||
{hasFooter && (
|
||||
<StyledFooter divider={!!items.length}>
|
||||
<StyledButton onClick={onFooterButtonClick}>
|
||||
<IconPlus size={theme.icon.size.md} />
|
||||
{footerButtonLabel}
|
||||
</StyledButton>
|
||||
</StyledFooter>
|
||||
<StyledFooterContainer>
|
||||
<CardFooter divider={!!items.length}>
|
||||
<StyledButton onClick={onFooterButtonClick}>
|
||||
<IconPlus size={theme.icon.size.md} />
|
||||
{footerButtonLabel}
|
||||
</StyledButton>
|
||||
</CardFooter>
|
||||
</StyledFooterContainer>
|
||||
)}
|
||||
</Card>
|
||||
);
|
||||
|
||||
+48
-36
@@ -6,15 +6,17 @@ import { IconChevronRight, type IconComponent } from 'twenty-ui/display';
|
||||
import { CardContent } from 'twenty-ui/layout';
|
||||
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledRow = styled(CardContent)`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
font-size: ${themeCssVariables.font.size.sm};
|
||||
font-weight: ${themeCssVariables.font.weight.medium};
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
padding: ${themeCssVariables.spacing[2]};
|
||||
padding-left: ${themeCssVariables.spacing[3]};
|
||||
min-height: ${themeCssVariables.spacing[6]};
|
||||
const StyledRowContainer = styled.div`
|
||||
> * {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
font-size: ${themeCssVariables.font.size.sm};
|
||||
font-weight: ${themeCssVariables.font.weight.medium};
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
padding: ${themeCssVariables.spacing[2]};
|
||||
padding-left: ${themeCssVariables.spacing[3]};
|
||||
min-height: ${themeCssVariables.spacing[6]};
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledRightContainer = styled.div`
|
||||
@@ -43,9 +45,11 @@ const StyledDescription = styled.span`
|
||||
padding-left: ${themeCssVariables.spacing[1]};
|
||||
`;
|
||||
|
||||
const StyledLink = styled(Link)`
|
||||
color: ${themeCssVariables.font.color.secondary};
|
||||
text-decoration: none;
|
||||
const StyledLinkContainer = styled.div`
|
||||
> a {
|
||||
color: ${themeCssVariables.font.color.secondary};
|
||||
text-decoration: none;
|
||||
}
|
||||
`;
|
||||
|
||||
type SettingsListItemCardContentProps = {
|
||||
@@ -72,36 +76,44 @@ export const SettingsListItemCardContent = ({
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
const content = (
|
||||
<StyledRow
|
||||
onClick={onClick}
|
||||
divider={divider}
|
||||
isClickable={!!onClick || !!to}
|
||||
hasHoverHighlight={!!to}
|
||||
>
|
||||
{!!LeftIcon && (
|
||||
<LeftIcon
|
||||
size={theme.icon.size.md}
|
||||
color={LeftIconColor ?? 'currentColor'}
|
||||
/>
|
||||
)}
|
||||
<StyledContent>
|
||||
<StyledLabel>{label}</StyledLabel>
|
||||
{!!description && <StyledDescription>{description}</StyledDescription>}
|
||||
</StyledContent>
|
||||
<StyledRightContainer>
|
||||
{rightComponent}
|
||||
{!!to && (
|
||||
<IconChevronRight
|
||||
<StyledRowContainer>
|
||||
<CardContent
|
||||
onClick={onClick}
|
||||
divider={divider}
|
||||
isClickable={!!onClick || !!to}
|
||||
hasHoverHighlight={!!to}
|
||||
>
|
||||
{!!LeftIcon && (
|
||||
<LeftIcon
|
||||
size={theme.icon.size.md}
|
||||
color={theme.font.color.tertiary}
|
||||
color={LeftIconColor ?? 'currentColor'}
|
||||
/>
|
||||
)}
|
||||
</StyledRightContainer>
|
||||
</StyledRow>
|
||||
<StyledContent>
|
||||
<StyledLabel>{label}</StyledLabel>
|
||||
{!!description && (
|
||||
<StyledDescription>{description}</StyledDescription>
|
||||
)}
|
||||
</StyledContent>
|
||||
<StyledRightContainer>
|
||||
{rightComponent}
|
||||
{!!to && (
|
||||
<IconChevronRight
|
||||
size={theme.icon.size.md}
|
||||
color={theme.font.color.tertiary}
|
||||
/>
|
||||
)}
|
||||
</StyledRightContainer>
|
||||
</CardContent>
|
||||
</StyledRowContainer>
|
||||
);
|
||||
|
||||
if (isDefined(to)) {
|
||||
return <StyledLink to={to}>{content}</StyledLink>;
|
||||
return (
|
||||
<StyledLinkContainer>
|
||||
<Link to={to}>{content}</Link>
|
||||
</StyledLinkContainer>
|
||||
);
|
||||
}
|
||||
|
||||
return content;
|
||||
|
||||
@@ -2,9 +2,17 @@ import { styled } from '@linaria/react';
|
||||
import { Card } from 'twenty-ui/layout';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledCard = styled(Card)`
|
||||
background-color: ${themeCssVariables.background.secondary};
|
||||
const StyledCardContainer = styled.div`
|
||||
height: 40px;
|
||||
|
||||
> * {
|
||||
background-color: ${themeCssVariables.background.secondary};
|
||||
height: 100%;
|
||||
}
|
||||
`;
|
||||
|
||||
export { StyledCard as SettingsListSkeletonCard };
|
||||
export const SettingsListSkeletonCard = () => (
|
||||
<StyledCardContainer>
|
||||
<Card />
|
||||
</StyledCardContainer>
|
||||
);
|
||||
|
||||
+20
-12
@@ -1,6 +1,5 @@
|
||||
import { Separator } from '@/settings/components/Separator';
|
||||
import {
|
||||
StyledSettingsCardContent,
|
||||
StyledSettingsCardDescription,
|
||||
StyledSettingsCardIcon,
|
||||
StyledSettingsCardTextContainer,
|
||||
@@ -16,7 +15,12 @@ import {
|
||||
import { Toggle } from 'twenty-ui/input';
|
||||
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledSettingsCardToggleContent = styled(StyledSettingsCardContent)`
|
||||
const StyledSettingsCardToggleContent = styled.div<{ disabled?: boolean }>`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
gap: ${themeCssVariables.spacing[3]};
|
||||
background-color: ${themeCssVariables.background.secondary};
|
||||
padding: ${themeCssVariables.spacing[4]};
|
||||
cursor: ${({ disabled }) => (disabled ? 'default' : 'pointer')};
|
||||
position: relative;
|
||||
pointer-events: ${({ disabled }) => (disabled ? 'none' : 'auto')};
|
||||
@@ -26,7 +30,9 @@ const StyledSettingsCardToggleContent = styled(StyledSettingsCardContent)`
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledSettingsCardToggleButton = styled(Toggle)`
|
||||
const StyledSettingsCardToggleButtonContainer = styled.span`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
margin-left: auto;
|
||||
`;
|
||||
@@ -84,15 +90,17 @@ export const SettingsOptionCardContentToggle = ({
|
||||
</StyledSettingsCardDescription>
|
||||
)}
|
||||
</StyledSettingsCardTextContainer>
|
||||
<StyledSettingsCardToggleButton
|
||||
id={toggleId}
|
||||
value={checked}
|
||||
onChange={onChange}
|
||||
disabled={disabled}
|
||||
toggleSize="small"
|
||||
color={advancedMode ? theme.color.yellow : theme.color.blue}
|
||||
centered={toggleCentered}
|
||||
/>
|
||||
<StyledSettingsCardToggleButtonContainer>
|
||||
<Toggle
|
||||
id={toggleId}
|
||||
value={checked}
|
||||
onChange={onChange}
|
||||
disabled={disabled}
|
||||
toggleSize="small"
|
||||
color={advancedMode ? theme.color.yellow : theme.color.blue}
|
||||
centered={toggleCentered}
|
||||
/>
|
||||
</StyledSettingsCardToggleButtonContainer>
|
||||
</StyledSettingsCardToggleContent>
|
||||
{divider && <Separator />}
|
||||
</>
|
||||
|
||||
@@ -5,22 +5,26 @@ import { type IconComponent } from 'twenty-ui/display';
|
||||
import { Radio } from 'twenty-ui/input';
|
||||
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledRadioCardContent = styled(CardContent)`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: ${themeCssVariables.spacing[2]};
|
||||
border: 1px solid ${themeCssVariables.border.color.medium};
|
||||
border-radius: ${themeCssVariables.border.radius.sm};
|
||||
flex-grow: 1;
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
cursor: pointer;
|
||||
const StyledRadioCardContentContainer = styled.div`
|
||||
> * {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: ${themeCssVariables.spacing[2]};
|
||||
border: 1px solid ${themeCssVariables.border.color.medium};
|
||||
border-radius: ${themeCssVariables.border.radius.sm};
|
||||
flex-grow: 1;
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background: ${themeCssVariables.background.transparent.lighter};
|
||||
&:hover {
|
||||
background: ${themeCssVariables.background.transparent.lighter};
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledRadio = styled(Radio)`
|
||||
const StyledRadioContainer = styled.span`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
margin-left: auto;
|
||||
padding: ${themeCssVariables.spacing[1]};
|
||||
`;
|
||||
@@ -58,13 +62,17 @@ export const SettingsRadioCard = ({
|
||||
const onClick = () => handleSelect(value);
|
||||
|
||||
return (
|
||||
<StyledRadioCardContent tabIndex={0} onClick={onClick}>
|
||||
{Icon && <Icon size={theme.icon.size.xl} color={theme.color.gray10} />}
|
||||
<span>
|
||||
{title && <StyledTitle>{title}</StyledTitle>}
|
||||
{description && <StyledDescription>{description}</StyledDescription>}
|
||||
</span>
|
||||
<StyledRadio value={value} checked={isSelected} />
|
||||
</StyledRadioCardContent>
|
||||
<StyledRadioCardContentContainer>
|
||||
<CardContent tabIndex={0} onClick={onClick}>
|
||||
{Icon && <Icon size={theme.icon.size.xl} color={theme.color.gray10} />}
|
||||
<span>
|
||||
{title && <StyledTitle>{title}</StyledTitle>}
|
||||
{description && <StyledDescription>{description}</StyledDescription>}
|
||||
</span>
|
||||
<StyledRadioContainer>
|
||||
<Radio value={value} checked={isSelected} />
|
||||
</StyledRadioContainer>
|
||||
</CardContent>
|
||||
</StyledRadioCardContentContainer>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -8,12 +8,14 @@ type SettingsSummaryCardProps = {
|
||||
rightComponent: ReactNode;
|
||||
};
|
||||
|
||||
const StyledCardContent = styled(CardContent)`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
padding: ${themeCssVariables.spacing[2]};
|
||||
min-height: ${themeCssVariables.spacing[6]};
|
||||
const StyledCardContentContainer = styled.div`
|
||||
> * {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
padding: ${themeCssVariables.spacing[2]};
|
||||
min-height: ${themeCssVariables.spacing[6]};
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledTitle = styled.div`
|
||||
@@ -29,9 +31,11 @@ export const SettingsSummaryCard = ({
|
||||
rightComponent,
|
||||
}: SettingsSummaryCardProps) => (
|
||||
<Card>
|
||||
<StyledCardContent>
|
||||
<StyledTitle>{title}</StyledTitle>
|
||||
{rightComponent}
|
||||
</StyledCardContent>
|
||||
<StyledCardContentContainer>
|
||||
<CardContent>
|
||||
<StyledTitle>{title}</StyledTitle>
|
||||
{rightComponent}
|
||||
</CardContent>
|
||||
</StyledCardContentContainer>
|
||||
</Card>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user