Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix noninteractive toggle #8383

Merged
merged 4 commits into from
Nov 8, 2024
Merged

Fix noninteractive toggle #8383

merged 4 commits into from
Nov 8, 2024

Conversation

Devessier
Copy link
Contributor

  • 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.

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Summary

This PR enhances toggle component accessibility and mobile responsiveness across settings pages by introducing a new SettingsOptionCardContentWithToggle component and improving existing toggle implementations.

  • Added new SettingsOptionCardContentWithToggle component in /packages/twenty-front/src/modules/settings/components/SettingsOptionCardContentWithToggle.tsx with label-based click handling
  • Modified /packages/twenty-ui/src/input/components/Toggle.tsx to prevent shrinking on mobile with flex-shrink: 0
  • Replaced direct click handlers with onChange handlers across settings components for better accessibility
  • Added useId hook for toggle accessibility in card content components
  • Standardized toggle behavior across calendar, message, and security settings pages

6 file(s) reviewed, 7 comment(s)
Edit PR Review Bot Settings | Greptile

Comment on lines +71 to +75
onChange={() => {
handleContactAutoCreationToggle(
!calendarChannel.isContactAutoCreationEnabled,
)
}
>
<StyledToggle
value={calendarChannel.isContactAutoCreationEnabled}
/>
</SettingsOptionCardContent>
);
}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Unnecessary arrow function wrapper. Pass handleContactAutoCreationToggle directly as the onChange prop.

Comment on lines 67 to 76
<SettingsOptionCardContentWithToggle
title="Auto-creation"
description="Automatically create contacts for people."
onClick={() =>
checked={calendarChannel.isContactAutoCreationEnabled}
onChange={() => {
handleContactAutoCreationToggle(
!calendarChannel.isContactAutoCreationEnabled,
)
}
>
<StyledToggle
value={calendarChannel.isContactAutoCreationEnabled}
/>
</SettingsOptionCardContent>
);
}}
/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Missing aria-label for better screen reader support since this toggle affects important functionality.

onChange={() => {
handleIsNonProfessionalEmailExcludedToggle(
!messageChannel.excludeNonProfessionalEmails,
)
}
>
<StyledToggle value={messageChannel.excludeNonProfessionalEmails} />
</SettingsOptionCardContent>
<SettingsOptionCardContent
);
}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Unnecessary arrow function wrapper adds complexity. Can directly pass the handler

Comment on lines 19 to +21
cursor: pointer;
position: relative;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: cursor: pointer without click handler may be misleading to users

Comment on lines 10 to 14
const StyledCover = styled.span`
cursor: pointer;
inset: 0;
position: absolute;
`;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: StyledCover overlays the entire card area but may interfere with text selection. Consider using pointer-events: none on text elements if needed.

Comment on lines 36 to 41
<label htmlFor={toggleId}>
{title}

<StyledCover />
</label>
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Label wrapping may cause accessibility issues since it contains a clickable cover. Consider using aria-labelledby instead.

Icon={Icon}
divider={divider}
>
<StyledToggle id={toggleId} value={checked} onChange={onChange} />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Missing aria-label on toggle for screen readers when title is not directly associated

@Devessier Devessier force-pushed the fix-noninteractive-toggle branch from 30d969a to 512aa1f Compare November 8, 2024 09:20
@charlesBochet charlesBochet merged commit f3e3c18 into main Nov 8, 2024
19 checks passed
@charlesBochet charlesBochet deleted the fix-noninteractive-toggle branch November 8, 2024 11:42
@@ -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}
Copy link
Contributor

@AMoreaux AMoreaux Nov 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Devessier I'm encountering a problem with this implementation. Since we need to use inputs other than a checkbox, we should use a slot instead of a prop.

https://www.figma.com/design/xt8O9mFeLl46C5InWwoMrN/Twenty?node-id=42308-234697&t=YrBrHCCvLIyihv7X-4

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great point. We chose to restrict minimize the API surface with @charlesBochet as all Cards were relying on a Toggle component. We can modify the API have one version for toggles and one for inputs, etc.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WDYT of this implementation:
https://github.com/twentyhq/twenty/pull/8378/files#diff-778c43a88bc2aed0767352fe3e86f1d8a49204de88fd23a6bd891127e0a4a98cR183-R196

We keep the label implementation with the flexibility to use custom input in the card.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great point. We chose to restrict minimize the API surface with @charlesBochet as all Cards were relying on a Toggle component. We can modify the API have one version for toggles and one for inputs, etc.

I didn't saw the answer 😅
I'll rollback. Thx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants