diff --git a/packages/twenty-front/src/modules/settings/components/AdvancedSettingsContentWrapperWithDot.tsx b/packages/twenty-front/src/modules/settings/components/AdvancedSettingsContentWrapperWithDot.tsx new file mode 100644 index 000000000..a657a633a --- /dev/null +++ b/packages/twenty-front/src/modules/settings/components/AdvancedSettingsContentWrapperWithDot.tsx @@ -0,0 +1,59 @@ +import { useTheme } from '@emotion/react'; +import styled from '@emotion/styled'; +import { IconPoint } from 'twenty-ui'; + +const StyledWrapper = styled.div` + position: relative; + width: 100%; +`; +type DotPosition = 'top' | 'centered'; + +type AdvancedSettingsContentWrapperWithDotProps = { + children: React.ReactNode; + hideDot?: boolean; + dotPosition?: DotPosition; +}; + +const StyledDotContainer = styled.div<{ dotPosition: DotPosition }>` + display: flex; + position: absolute; + height: 100%; + left: ${({ theme }) => theme.spacing(-5)}; + + ${({ dotPosition }) => { + if (dotPosition === 'top') { + return ` + top: 0; + `; + } + return ` + align-items: center; + `; + }} +`; + +const StyledIconPoint = styled(IconPoint)` + margin-right: 0; +`; + +export const AdvancedSettingsContentWrapperWithDot = ({ + children, + hideDot = false, + dotPosition = 'centered', +}: AdvancedSettingsContentWrapperWithDotProps) => { + const theme = useTheme(); + return ( + + {!hideDot && ( + + + + )} + {children} + + ); +}; diff --git a/packages/twenty-front/src/modules/settings/components/AdvancedSettingsWrapper.tsx b/packages/twenty-front/src/modules/settings/components/AdvancedSettingsWrapper.tsx index 4aadc5f6c..4084887ac 100644 --- a/packages/twenty-front/src/modules/settings/components/AdvancedSettingsWrapper.tsx +++ b/packages/twenty-front/src/modules/settings/components/AdvancedSettingsWrapper.tsx @@ -1,41 +1,14 @@ +import { AdvancedSettingsContentWrapperWithDot } from '@/settings/components/AdvancedSettingsContentWrapperWithDot'; import { ADVANCED_SETTINGS_ANIMATION_DURATION } from '@/settings/constants/AdvancedSettingsAnimationDurations'; import { isAdvancedModeEnabledState } from '@/ui/navigation/navigation-drawer/states/isAdvancedModeEnabledState'; import styled from '@emotion/styled'; import { useRecoilValue } from 'recoil'; -import { AnimatedExpandableContainer, IconPoint, MAIN_COLORS } from 'twenty-ui'; - -type DotPosition = 'top' | 'centered'; - -const StyledAdvancedWrapper = styled.div` - position: relative; - width: 100%; -`; - -const StyledDotContainer = styled.div<{ dotPosition: DotPosition }>` - display: flex; - position: absolute; - height: 100%; - left: ${({ theme }) => theme.spacing(-5)}; - - ${({ dotPosition }) => { - if (dotPosition === 'top') { - return ` - top: 0; - `; - } - return ` - align-items: center; - `; - }} -`; - +import { AnimatedExpandableContainer } from 'twenty-ui'; const StyledContent = styled.div` width: 100%; `; -const StyledIconPoint = styled(IconPoint)` - margin-right: 0; -`; +type DotPosition = 'top' | 'centered'; type AdvancedSettingsWrapperProps = { children: React.ReactNode; @@ -60,18 +33,12 @@ export const AdvancedSettingsWrapper = ({ mode="scroll-height" containAnimation={false} > - - {!hideDot && ( - - - - )} + {children} - + ); }; diff --git a/packages/twenty-front/src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldIconLabelForm.tsx b/packages/twenty-front/src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldIconLabelForm.tsx index 934425ff7..ee04cfca8 100644 --- a/packages/twenty-front/src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldIconLabelForm.tsx +++ b/packages/twenty-front/src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldIconLabelForm.tsx @@ -4,6 +4,7 @@ import { z } from 'zod'; import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; import { fieldMetadataItemSchema } from '@/object-metadata/validation-schemas/fieldMetadataItemSchema'; +import { AdvancedSettingsContentWrapperWithDot } from '@/settings/components/AdvancedSettingsContentWrapperWithDot'; import { AdvancedSettingsWrapper } from '@/settings/components/AdvancedSettingsWrapper'; import { SettingsOptionCardContentToggle } from '@/settings/components/SettingsOptions/SettingsOptionCardContentToggle'; import { DATABASE_IDENTIFIER_MAXIMUM_LENGTH } from '@/settings/data-model/constants/DatabaseIdentifierMaximumLength'; @@ -47,7 +48,7 @@ type SettingsDataModelFieldIconLabelFormValues = z.infer< const StyledInputsContainer = styled.div` display: flex; gap: ${({ theme }) => theme.spacing(2)}; - margin-bottom: ${({ theme }) => theme.spacing(2)}; + margin-bottom: ${({ theme }) => theme.spacing(1)}; width: 100%; `; @@ -86,6 +87,7 @@ export const SettingsDataModelFieldIconLabelForm = ({ setValue, watch, formState: { errors }, + trigger, } = useFormContext(); const theme = useTheme(); @@ -135,6 +137,7 @@ export const SettingsDataModelFieldIconLabelForm = ({ value={value} onChange={(value) => { onChange(value); + trigger('label'); if (isLabelSyncedWithName === true) { fillNameFromLabel(value); } @@ -152,8 +155,8 @@ export const SettingsDataModelFieldIconLabelForm = ({ /> {canToggleSyncLabelWithName && ( - - + + @@ -207,27 +210,32 @@ export const SettingsDataModelFieldIconLabelForm = ({ fieldMetadataItem?.isLabelSyncedWithName ?? true } render={({ field: { onChange, value } }) => ( - - { - onChange(value); - if (value === true) { - fillNameFromLabel(label); - } - }} - /> - + + + { + onChange(value); + if (value === true) { + fillNameFromLabel(label); + } + }} + /> + + )} /> - - + + )} ); diff --git a/packages/twenty-front/src/modules/ui/input/components/InputErrorHelper.tsx b/packages/twenty-front/src/modules/ui/input/components/InputErrorHelper.tsx index 1a8a38f0e..9d20e6962 100644 --- a/packages/twenty-front/src/modules/ui/input/components/InputErrorHelper.tsx +++ b/packages/twenty-front/src/modules/ui/input/components/InputErrorHelper.tsx @@ -5,10 +5,7 @@ const StyledInputErrorHelper = styled.div` color: ${({ theme }) => theme.color.red}; font-size: ${({ theme }) => theme.font.size.xs}; position: absolute; -`; - -const StyledErrorContainer = styled.div` - margin-top: ${({ theme }) => theme.spacing(1)}; + top: calc(100% + ${({ theme }) => theme.spacing(0.25)}); `; export const InputErrorHelper = ({ @@ -16,11 +13,11 @@ export const InputErrorHelper = ({ }: { children?: React.ReactNode; }) => ( - +
{children && ( {children} )} - +
); diff --git a/packages/twenty-front/src/modules/ui/input/components/TextInputV2.tsx b/packages/twenty-front/src/modules/ui/input/components/TextInputV2.tsx index 3f52d8dfb..bf1a0e0c0 100644 --- a/packages/twenty-front/src/modules/ui/input/components/TextInputV2.tsx +++ b/packages/twenty-front/src/modules/ui/input/components/TextInputV2.tsx @@ -22,6 +22,7 @@ const StyledContainer = styled.div< display: inline-flex; flex-direction: column; width: ${({ fullWidth }) => (fullWidth ? `100%` : 'auto')}; + position: relative; `; const StyledInputContainer = styled.div`