From f3e3c186dcd87aed8b99b4db21e18af836f39974 Mon Sep 17 00:00:00 2001 From: Baptiste Devessier Date: Fri, 8 Nov 2024 12:42:15 +0100 Subject: [PATCH] Fix noninteractive toggle (#8383) - Use a label to make the whole card interactive - Disallow the Toggle component to shrink; it used to on mobile devices A focus indicator is missing for the Toggle component. We'll have to add one. --- ...SettingsAccountsCalendarChannelDetails.tsx | 19 +++----- .../SettingsAccountsMessageChannelDetails.tsx | 24 ++++------- .../components/SettingsOptionCardContent.tsx | 43 ++++++++++++++----- .../SettingsSecurityOptionsList.tsx | 21 +++++---- .../twenty-ui/src/input/components/Toggle.tsx | 1 + 5 files changed, 58 insertions(+), 50 deletions(-) diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarChannelDetails.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarChannelDetails.tsx index 7232d712d..d017bf42d 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarChannelDetails.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarChannelDetails.tsx @@ -5,7 +5,7 @@ import { SettingsAccountsEventVisibilitySettingsCard } from '@/settings/accounts import { SettingsOptionCardContent } from '@/settings/components/SettingsOptionCardContent'; import styled from '@emotion/styled'; import { Section } from '@react-email/components'; -import { Card, H2Title, Toggle } from 'twenty-ui'; +import { Card, H2Title } from 'twenty-ui'; import { CalendarChannelVisibility } from '~/generated-metadata/graphql'; const StyledDetailsContainer = styled.div` @@ -21,10 +21,6 @@ type SettingsAccountsCalendarChannelDetailsProps = { >; }; -const StyledToggle = styled(Toggle)` - margin-left: auto; -`; - export const SettingsAccountsCalendarChannelDetails = ({ calendarChannel, }: SettingsAccountsCalendarChannelDetailsProps) => { @@ -71,16 +67,13 @@ export const SettingsAccountsCalendarChannelDetails = ({ + checked={calendarChannel.isContactAutoCreationEnabled} + onChange={() => { handleContactAutoCreationToggle( !calendarChannel.isContactAutoCreationEnabled, - ) - } - > - - + ); + }} + /> diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageChannelDetails.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageChannelDetails.tsx index 1c9bb6821..d4ae356a5 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageChannelDetails.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageChannelDetails.tsx @@ -1,5 +1,5 @@ import styled from '@emotion/styled'; -import { Card, H2Title, Section, Toggle } from 'twenty-ui'; +import { Card, H2Title, Section } from 'twenty-ui'; import { MessageChannel, @@ -30,10 +30,6 @@ const StyledDetailsContainer = styled.div` gap: ${({ theme }) => theme.spacing(6)}; `; -const StyledToggle = styled(Toggle)` - margin-left: auto; -`; - export const SettingsAccountsMessageChannelDetails = ({ messageChannel, }: SettingsAccountsMessageChannelDetailsProps) => { @@ -107,25 +103,23 @@ export const SettingsAccountsMessageChannelDetails = ({ title="Exclude non-professional emails" description="Don’t create contacts from/to Gmail, Outlook emails" divider - onClick={() => + checked={messageChannel.excludeNonProfessionalEmails} + onChange={() => { handleIsNonProfessionalEmailExcludedToggle( !messageChannel.excludeNonProfessionalEmails, - ) - } - > - - + ); + }} + /> + checked={messageChannel.excludeGroupEmails} + onChange={() => handleIsGroupEmailExcludedToggle( !messageChannel.excludeGroupEmails, ) } - > - - + /> diff --git a/packages/twenty-front/src/modules/settings/components/SettingsOptionCardContent.tsx b/packages/twenty-front/src/modules/settings/components/SettingsOptionCardContent.tsx index 7384b1d58..3628119fb 100644 --- a/packages/twenty-front/src/modules/settings/components/SettingsOptionCardContent.tsx +++ b/packages/twenty-front/src/modules/settings/components/SettingsOptionCardContent.tsx @@ -1,16 +1,16 @@ -import styled from '@emotion/styled'; import { useTheme } from '@emotion/react'; +import styled from '@emotion/styled'; -import { IconComponent, CardContent } from 'twenty-ui'; -import { ReactNode } from 'react'; +import { useId } from 'react'; +import { CardContent, IconComponent, Toggle } from 'twenty-ui'; type SettingsOptionCardContentProps = { Icon?: IconComponent; - title: string; + title: React.ReactNode; description: string; - onClick: () => void; - children: ReactNode; divider?: boolean; + checked: boolean; + onChange: (checked: boolean) => void; }; const StyledCardContent = styled(CardContent)` @@ -18,6 +18,7 @@ const StyledCardContent = styled(CardContent)` display: flex; gap: ${({ theme }) => theme.spacing(4)}; cursor: pointer; + position: relative; &:hover { background: ${({ theme }) => theme.background.transparent.lighter}; @@ -47,28 +48,48 @@ const StyledIcon = styled.div` min-width: ${({ theme }) => theme.icon.size.md}; `; +const StyledToggle = styled(Toggle)` + margin-left: auto; +`; + +const StyledCover = styled.span` + cursor: pointer; + inset: 0; + position: absolute; +`; + export const SettingsOptionCardContent = ({ Icon, title, description, - onClick, - children, divider, + checked, + onChange, }: SettingsOptionCardContentProps) => { const theme = useTheme(); + const toggleId = useId(); + return ( - + {Icon && ( )} +
- {title} + + + {description}
- {children} + +
); }; diff --git a/packages/twenty-front/src/modules/settings/security/components/SettingsSecurityOptionsList.tsx b/packages/twenty-front/src/modules/settings/security/components/SettingsSecurityOptionsList.tsx index f7b9dc2ad..ac5eef959 100644 --- a/packages/twenty-front/src/modules/settings/security/components/SettingsSecurityOptionsList.tsx +++ b/packages/twenty-front/src/modules/settings/security/components/SettingsSecurityOptionsList.tsx @@ -2,21 +2,21 @@ import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState'; import { SettingsOptionCardContent } from '@/settings/components/SettingsOptionCardContent'; import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar'; import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; -import styled from '@emotion/styled'; import { useRecoilState } from 'recoil'; -import { Card, IconLink, Toggle } from 'twenty-ui'; +import { Card, IconLink, isDefined } from 'twenty-ui'; import { useUpdateWorkspaceMutation } from '~/generated/graphql'; -const StyledToggle = styled(Toggle)` - margin-left: auto; -`; - export const SettingsSecurityOptionsList = () => { const { enqueueSnackBar } = useSnackBar(); const [currentWorkspace, setCurrentWorkspace] = useRecoilState( currentWorkspaceState, ); + if (!isDefined(currentWorkspace)) { + throw new Error( + 'The current workspace must be defined to edit its security options.', + ); + } const [updateWorkspace] = useUpdateWorkspaceMutation(); @@ -49,12 +49,11 @@ export const SettingsSecurityOptionsList = () => { Icon={IconLink} title="Invite by Link" description="Allow the invitation of new users by sharing an invite link." - onClick={() => - handleChange(!currentWorkspace?.isPublicInviteLinkEnabled) + checked={currentWorkspace.isPublicInviteLinkEnabled} + onChange={() => + handleChange(!currentWorkspace.isPublicInviteLinkEnabled) } - > - - + /> ); }; diff --git a/packages/twenty-ui/src/input/components/Toggle.tsx b/packages/twenty-ui/src/input/components/Toggle.tsx index 86b997510..c9f95385d 100644 --- a/packages/twenty-ui/src/input/components/Toggle.tsx +++ b/packages/twenty-ui/src/input/components/Toggle.tsx @@ -12,6 +12,7 @@ type ContainerProps = { }; const StyledContainer = styled.label` + flex-shrink: 0; align-items: center; background-color: ${({ theme, isOn, color }) => isOn ? (color ?? theme.color.blue) : theme.background.transparent.medium};