Skip to content

fix: Making the hidden input on Checkbox and Switch only cover the indicator and not also the label#24638

Merged
khmakoto merged 7 commits intomicrosoft:masterfrom
khmakoto:checkboxSwitchInputOnlyCoversIndicator
Sep 29, 2022
Merged

fix: Making the hidden input on Checkbox and Switch only cover the indicator and not also the label#24638
khmakoto merged 7 commits intomicrosoft:masterfrom
khmakoto:checkboxSwitchInputOnlyCoversIndicator

Conversation

@khmakoto
Copy link
Member

@khmakoto khmakoto commented Sep 1, 2022

Current Behavior

The hidden input in the Checkbox and Switch components covers both the indicator and the label, making any interactive elements within the label, like links, impossible to be clicked.

Input

image

image

Label

image

image

New Behavior

The hidden input in the Checkbox and Switch components now covers only the indicator and its surrounding space, not the label. This makes any interactive elements within the label, like links, possible to be clicked. We verified that clicking on the label still toggles the state of the component. We also expanded the size of the label so it covers the empty space around it that was previously being covered by the hidden input.

We verified that hover and pressed styling still works as expected and we have added visual regression tests that check for RTL to work correctly as well.

Input

image

image

Label

image

image

Related Issue(s)

Fixes #24330

Humberto Makoto Morimoto Burgos added 2 commits September 1, 2022 12:10
Copy link
Contributor

@behowell behowell left a comment

Choose a reason for hiding this comment

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

This change will also make it so the padding around the control, and the gap between the control and the label are dead zones, but they are required to be part of the hit target by the spec (and in general for usability).

Interactive content should probably be outside the label? But if it's necessary to do it this way, then we should consider refactoring Checkbox/Switch/Radio so that the <label> is the root element, wrapping the indicator and label text.

We should make sure that Radio also works the same way as Checkbox and Switch.

@fabricteam
Copy link
Collaborator

fabricteam commented Sep 1, 2022

📊 Bundle size report

Package & Exports Baseline (minified/GZIP) PR Change
react-switch
Switch
32.097 kB
10.27 kB
33.534 kB
10.635 kB
1.437 kB
365 B
Unchanged fixtures
Package & Exports Size (minified/GZIP)
react-components
react-components: Accordion, Button, FluentProvider, Image, Menu, Popover
188.681 kB
52.366 kB
react-components
react-components: FluentProvider & webLightTheme
33.394 kB
11.007 kB
react-portal-compat
PortalCompatProvider
5.851 kB
1.964 kB
🤖 This report was generated against 8f38bb63574e31bf2fa9f2f1d14b166d6c1a627f

@codesandbox-ci
Copy link

codesandbox-ci bot commented Sep 1, 2022

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit f2dac77:

Sandbox Source
@fluentui/react 8 starter Configuration
@fluentui/react-components 9 starter Configuration

@size-auditor
Copy link

size-auditor bot commented Sep 1, 2022

Asset size changes

Size Auditor did not detect a change in bundle size for any component!

Baseline commit: 8f38bb63574e31bf2fa9f2f1d14b166d6c1a627f (build)

@fabricteam
Copy link
Collaborator

fabricteam commented Sep 1, 2022

Perf Analysis (@fluentui/react-components)

No significant results to display.

All results

Scenario Render type Master Ticks PR Ticks Iterations Status
Avatar mount 1300 1257 5000
Button mount 939 934 5000
FluentProvider mount 1478 1510 5000
FluentProviderWithTheme mount 581 564 10
FluentProviderWithTheme virtual-rerender 544 540 10
FluentProviderWithTheme virtual-rerender-with-unmount 563 575 10
MakeStyles mount 1934 1975 50000
SpinButton mount 2324 2341 5000

Copy link
Contributor

@smhigley smhigley left a comment

Choose a reason for hiding this comment

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

I can't tell what the difference is in the screener change and the update looks fine, so seems good to me :)

@smhigley
Copy link
Contributor

smhigley commented Sep 2, 2022

re: @behowell's comment on dead zones -- I agree it'd be better if there weren't, though it doesn't concern me all that much, since the indicator itself combined with the label text itself should end up being a pretty big hit target.

A wrapping label would be nice though :). I forget if there was a reason for not doing that originally for checkbox/switch.

@msft-fluent-ui-bot
Copy link
Collaborator

This pull request has been automatically marked as stale because it was marked as requiring author feedback but has not had any activity for 7 days. It will be closed if no further activity occurs within 5 days of this comment. Thank you for your contributions to Fluent UI!

@khmakoto khmakoto requested a review from behowell September 27, 2022 23:46
Comment on lines 215 to 225
// Use a (negative) margin to account for the difference between the indicator's height and the label's line height,
// as well as accounting for the introduced padding for handling the "empty space" around the label.
// This prevents the label from expanding the height of the checkbox, but preserves line height if the label wraps.
medium: {
marginTop: `calc((${indicatorSizeMedium} - ${tokens.lineHeightBase300}) / 2)`,
marginBottom: `calc((${indicatorSizeMedium} - ${tokens.lineHeightBase300}) / 2)`,
marginTop: `calc(-1 * ${tokens.spacingVerticalS} + (${indicatorSizeMedium} - ${tokens.lineHeightBase300}) / 2)`,
marginBottom: `calc(-1 * ${tokens.spacingVerticalS} + (${indicatorSizeMedium} - ${tokens.lineHeightBase300}) / 2)`,
},
large: {
marginTop: `calc((${indicatorSizeLarge} - ${tokens.lineHeightBase300}) / 2)`,
marginBottom: `calc((${indicatorSizeLarge} - ${tokens.lineHeightBase300}) / 2)`,
marginTop: `calc(-1 * ${tokens.spacingVerticalS} + (${indicatorSizeLarge} - ${tokens.lineHeightBase300}) / 2)`,
marginBottom: `calc(-1 * ${tokens.spacingVerticalS} + (${indicatorSizeLarge} - ${tokens.lineHeightBase300}) / 2)`,
},
Copy link
Contributor

Choose a reason for hiding this comment

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

IMO it would be better to remove the padding from root and put it on the individual slots instead of adding padding to both the label AND the root, then adding a negative margin to overlap it.

Copy link
Member Author

Choose a reason for hiding this comment

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

Agreed and done!

@khmakoto khmakoto requested a review from a team as a code owner September 28, 2022 23:10
Copy link
Contributor

@behowell behowell left a comment

Choose a reason for hiding this comment

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

Looks good, thanks for making all of these changes to address my feedback!

Comment on lines +153 to +158
medium: {
width: `calc(${indicatorSizeMedium} + ${tokens.spacingHorizontalS})`,
},
large: {
width: `calc(${indicatorSizeLarge} + ${tokens.spacingHorizontalS})`,
},
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you can get rid of spacingHorizontalS now that the label is using padding instead of margin for the gap, right?

Suggested change
medium: {
width: `calc(${indicatorSizeMedium} + ${tokens.spacingHorizontalS})`,
},
large: {
width: `calc(${indicatorSizeLarge} + ${tokens.spacingHorizontalS})`,
},
medium: {
width: indicatorSizeMedium,
},
large: {
width: indicatorSizeLarge,
},

Copy link
Member Author

Choose a reason for hiding this comment

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

No, that spacing is to account for the space on the left of the indicator (right if labelPosition is before). You can see that another tokens.spacingHorizontalM has been removed already that referred to the gap between the indicator and the label.


// Calculate the width of the hidden input by taking into account the size of the indicator + the padding around it.
// This is done so that clicking on that "empty space" still toggles the switch.
width: `calc(${trackWidth}px + ${tokens.spacingHorizontalS})`,
Copy link
Contributor

Choose a reason for hiding this comment

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

I haven't read the switch styles in as much detail, but similar to my comment here in checkbox, does this still need spacingHorizontalS included in it?

Suggested change
width: `calc(${trackWidth}px + ${tokens.spacingHorizontalS})`,
width: `${trackWidth}px`,

Copy link
Member Author

Choose a reason for hiding this comment

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

Yup, similar reason to the one above.

},
above: {
bottom: 0,
height: `calc(${trackHeight}px + ${tokens.spacingVerticalS})`,
Copy link
Contributor

Choose a reason for hiding this comment

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

Ditto here too

Suggested change
height: `calc(${trackHeight}px + ${tokens.spacingVerticalS})`,
height: `${trackHeight}px`,

Copy link
Member Author

Choose a reason for hiding this comment

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

Ditto.

@khmakoto khmakoto enabled auto-merge (squash) September 29, 2022 01:07
@khmakoto khmakoto closed this Sep 29, 2022
auto-merge was automatically disabled September 29, 2022 01:08

Pull request was closed

@khmakoto khmakoto reopened this Sep 29, 2022
@khmakoto khmakoto enabled auto-merge (squash) September 29, 2022 01:08
@khmakoto
Copy link
Member Author

@microsoft-github-policy-service agree [company="Microsoft"]

@khmakoto
Copy link
Member Author

@microsoft-github-policy-service agree company="Microsoft"

@khmakoto khmakoto merged commit e44263f into microsoft:master Sep 29, 2022
@khmakoto khmakoto deleted the checkboxSwitchInputOnlyCoversIndicator branch September 29, 2022 01:46
NotWoods pushed a commit to NotWoods/fluentui that referenced this pull request Nov 18, 2022
…dicator and not also the label (microsoft#24638)

* fix: Making the hidden input on Checkbox and Switch only cover the indicator and not also the label.

* Adding change files.

* Making empty space around indicator and label toggle checkbox when clicked.

* Making empty space around indicator and label toggle switch when clicked.

* Using indicator + label paddings instead of double paddings with negative margins and adding RTL VR tests.

* Addressing cases where no label is provided for components.

Co-authored-by: Humberto Makoto Morimoto Burgos <makotom@microsoft.com>
Co-authored-by: KHMakoto <humberto_makoto@hotmail.com>
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.

[Bug] react-checkbox: interactive items within the label are unreachable with a pointer

5 participants