Fix-inline-height (#11608)

Follow up from inline height #11553 related to PR #11442


we had some issues with hover styles

Fixes
https://github.com/twentyhq/twenty/issues/11442#issuecomment-2805893663

---------

Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Guillim
2025-04-16 17:49:04 +02:00
committed by GitHub
parent e1b99a6f39
commit b6901a49bf
10 changed files with 53 additions and 35 deletions

View File

@ -1,7 +1,7 @@
import { isNonEmptyString } from '@sniptt/guards'; import { isNonEmptyString } from '@sniptt/guards';
import { useFullNameFieldDisplay } from '@/object-record/record-field/meta-types/hooks/useFullNameFieldDisplay'; import { useFullNameFieldDisplay } from '@/object-record/record-field/meta-types/hooks/useFullNameFieldDisplay';
import { OverflowingTextWithTooltip } from 'twenty-ui/display'; import { TextDisplay } from '@/ui/field/display/components/TextDisplay';
export const FullNameFieldDisplay = () => { export const FullNameFieldDisplay = () => {
const { fieldValue } = useFullNameFieldDisplay(); const { fieldValue } = useFullNameFieldDisplay();
@ -10,5 +10,5 @@ export const FullNameFieldDisplay = () => {
.filter(isNonEmptyString) .filter(isNonEmptyString)
.join(' '); .join(' ');
return <OverflowingTextWithTooltip text={content} />; return <TextDisplay text={content} />;
}; };

View File

@ -1,7 +1,7 @@
import { useNumberFieldDisplay } from '@/object-record/record-field/meta-types/hooks/useNumberFieldDisplay'; import { useNumberFieldDisplay } from '@/object-record/record-field/meta-types/hooks/useNumberFieldDisplay';
import { NumberDisplay } from '@/ui/field/display/components/NumberDisplay'; import { NumberDisplay } from '@/ui/field/display/components/NumberDisplay';
import { formatNumber } from '~/utils/format/number';
import { isDefined } from 'twenty-shared/utils'; import { isDefined } from 'twenty-shared/utils';
import { formatNumber } from '~/utils/format/number';
export const NumberFieldDisplay = () => { export const NumberFieldDisplay = () => {
const { fieldValue, fieldDefinition } = useNumberFieldDisplay(); const { fieldValue, fieldDefinition } = useNumberFieldDisplay();

View File

@ -10,12 +10,11 @@ export const TextFieldDisplay = () => {
? fieldDefinition.metadata?.settings?.displayedMaxRows ? fieldDefinition.metadata?.settings?.displayedMaxRows
: undefined; : undefined;
const displayMaxRowCalculated = displayedMaxRows
? displayedMaxRows
: displayedMaxRowsFromSettings;
return ( return (
<TextDisplay <TextDisplay text={fieldValue} displayedMaxRows={displayMaxRowCalculated} />
text={fieldValue}
displayedMaxRows={
displayedMaxRows ? displayedMaxRows : displayedMaxRowsFromSettings
}
/>
); );
}; };

View File

@ -48,10 +48,16 @@ const StyledRecordInlineCellNormalModeInnerContainer = styled.div`
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
padding-top: 2px;
padding-bottom: 2px;
`; `;
const StyledEmptyField = styled.div` const StyledEmptyField = styled.div`
color: ${({ theme }) => theme.font.color.light}; color: ${({ theme }) => theme.font.color.light};
height: 20px;
display: flex;
align-items: center;
`; `;
export const RecordInlineCellDisplayMode = ({ export const RecordInlineCellDisplayMode = ({

View File

@ -33,10 +33,9 @@ const StyledEmptyText = withTheme(styled.div<{ theme: Theme }>`
export const RecordTitleCellSingleTextDisplayMode = () => { export const RecordTitleCellSingleTextDisplayMode = () => {
const { recordId, fieldDefinition } = useContext(FieldContext); const { recordId, fieldDefinition } = useContext(FieldContext);
const recordValue = useRecordValue(recordId); const recordValue = useRecordValue(recordId);
const isEmpty = const isEmpty =
recordValue?.[fieldDefinition.metadata.fieldName].trim() === ''; recordValue?.[fieldDefinition.metadata.fieldName]?.trim() === '';
const { openInlineCell } = useInlineCell(); const { openInlineCell } = useInlineCell();

View File

@ -13,19 +13,25 @@ type BooleanDisplayProps = {
value: boolean | null | undefined; value: boolean | null | undefined;
}; };
const StyledContainer = styled.div`
height: 20px;
display: flex;
align-items: center;
`;
export const BooleanDisplay = ({ value }: BooleanDisplayProps) => { export const BooleanDisplay = ({ value }: BooleanDisplayProps) => {
if (value === null || value === undefined) { if (value === null || value === undefined) {
return <></>; return <StyledContainer />;
} }
const isTrue = value === true; const isTrue = value === true;
return ( return (
<> <StyledContainer>
{isTrue ? <IconCheck size={iconSizeSm} /> : <IconX size={iconSizeSm} />} {isTrue ? <IconCheck size={iconSizeSm} /> : <IconX size={iconSizeSm} />}
<StyledBooleanFieldValue> <StyledBooleanFieldValue>
{isTrue ? 'True' : 'False'} {isTrue ? 'True' : 'False'}
</StyledBooleanFieldValue> </StyledBooleanFieldValue>
</> </StyledContainer>
); );
}; };

View File

@ -1,26 +1,16 @@
import { useTheme } from '@emotion/react'; import { useTheme } from '@emotion/react';
import { styled } from '@linaria/react';
import { FieldCurrencyValue } from '@/object-record/record-field/types/FieldMetadata'; import { FieldCurrencyValue } from '@/object-record/record-field/types/FieldMetadata';
import { SETTINGS_FIELD_CURRENCY_CODES } from '@/settings/data-model/constants/SettingsFieldCurrencyCodes'; import { SETTINGS_FIELD_CURRENCY_CODES } from '@/settings/data-model/constants/SettingsFieldCurrencyCodes';
import { EllipsisDisplay } from '@/ui/field/display/components/EllipsisDisplay';
import { isDefined } from 'twenty-shared/utils';
import { formatAmount } from '~/utils/format/formatAmount'; import { formatAmount } from '~/utils/format/formatAmount';
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull'; import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
import { isDefined } from 'twenty-shared/utils';
type CurrencyDisplayProps = { type CurrencyDisplayProps = {
currencyValue: FieldCurrencyValue | null | undefined; currencyValue: FieldCurrencyValue | null | undefined;
}; };
const StyledEllipsisDisplay = styled.div`
align-items: center;
display: flex;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 100%;
`;
export const CurrencyDisplay = ({ currencyValue }: CurrencyDisplayProps) => { export const CurrencyDisplay = ({ currencyValue }: CurrencyDisplayProps) => {
const theme = useTheme(); const theme = useTheme();
@ -35,11 +25,11 @@ export const CurrencyDisplay = ({ currencyValue }: CurrencyDisplayProps) => {
: currencyValue?.amountMicros / 1000000; : currencyValue?.amountMicros / 1000000;
if (!shouldDisplayCurrency) { if (!shouldDisplayCurrency) {
return <StyledEllipsisDisplay>{0}</StyledEllipsisDisplay>; return <EllipsisDisplay>{0}</EllipsisDisplay>;
} }
return ( return (
<StyledEllipsisDisplay> <EllipsisDisplay>
{isDefined(CurrencyIcon) && amountToDisplay !== null && ( {isDefined(CurrencyIcon) && amountToDisplay !== null && (
<> <>
<CurrencyIcon <CurrencyIcon
@ -50,6 +40,6 @@ export const CurrencyDisplay = ({ currencyValue }: CurrencyDisplayProps) => {
</> </>
)} )}
{amountToDisplay !== null ? formatAmount(amountToDisplay) : ''} {amountToDisplay !== null ? formatAmount(amountToDisplay) : ''}
</StyledEllipsisDisplay> </EllipsisDisplay>
); );
}; };

View File

@ -1,6 +1,9 @@
import { styled } from '@linaria/react'; import { styled } from '@linaria/react';
const StyledEllipsisDisplay = styled.div<{ maxWidth?: number }>` const StyledEllipsisDisplay = styled.div<{ maxWidth?: number }>`
align-items: center;
display: flex;
height: 20px;
max-width: ${({ maxWidth }) => (maxWidth ? maxWidth + 'px' : '100%')}; max-width: ${({ maxWidth }) => (maxWidth ? maxWidth + 'px' : '100%')};
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;

View File

@ -1,3 +1,5 @@
import { styled } from '@linaria/react';
import { isUndefined } from '@sniptt/guards';
import { OverflowingTextWithTooltip } from 'twenty-ui/display'; import { OverflowingTextWithTooltip } from 'twenty-ui/display';
type TextDisplayProps = { type TextDisplayProps = {
@ -5,12 +7,22 @@ type TextDisplayProps = {
displayedMaxRows?: number; displayedMaxRows?: number;
}; };
const StyledContainer = styled.div<{ fixHeight: boolean }>`
height: ${({ fixHeight }) => (fixHeight ? '20px' : 'auto')};
display: flex;
align-items: center;
`;
export const TextDisplay = ({ text, displayedMaxRows }: TextDisplayProps) => { export const TextDisplay = ({ text, displayedMaxRows }: TextDisplayProps) => {
return ( return (
<OverflowingTextWithTooltip <StyledContainer
text={text} fixHeight={isUndefined(displayedMaxRows) || displayedMaxRows === 1}
displayedMaxRows={displayedMaxRows} >
isTooltipMultiline={true} <OverflowingTextWithTooltip
/> text={text}
displayedMaxRows={displayedMaxRows}
isTooltipMultiline={true}
/>
</StyledContainer>
); );
}; };

View File

@ -131,12 +131,15 @@ export default defineConfig(({ command, mode }) => {
'**/RecordTableTd.tsx', '**/RecordTableTd.tsx',
'**/RecordTableHeaderDragDropColumn.tsx', '**/RecordTableHeaderDragDropColumn.tsx',
'**/ActorDisplay.tsx', '**/ActorDisplay.tsx',
'**/BooleanDisplay.tsx',
'**/CurrencyDisplay.tsx',
'**/TextDisplay.tsx',
'**/EllipsisDisplay.tsx',
'**/AvatarChip.tsx', '**/AvatarChip.tsx',
'**/URLDisplay.tsx', '**/URLDisplay.tsx',
'**/EmailsDisplay.tsx', '**/EmailsDisplay.tsx',
'**/PhonesDisplay.tsx', '**/PhonesDisplay.tsx',
'**/MultiSelectDisplay.tsx', '**/MultiSelectDisplay.tsx',
], ],
babelOptions: { babelOptions: {
presets: ['@babel/preset-typescript', '@babel/preset-react'], presets: ['@babel/preset-typescript', '@babel/preset-react'],