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

Aligning switch semantics with aria role #2193

Merged
merged 2 commits into from
Aug 14, 2019

Conversation

myasonik
Copy link
Contributor

@myasonik myasonik commented Aug 2, 2019

Summary

Kibana was seeing issues with switches. Though we weren't able to figure out the root cause of the issue, switches have a unique aria role that they weren't taking advantage of. So, instead of continuing to dig, I thought I'd update the semantics skirting the issue a bit.

Following Inclusive Component's recommendation I've moved switches away from <input type=checkbox /> to <button role=switch aria-checked=true|false>.

  • Made sure the deprecation flow of shimming the event object works in Chrome/FF/Safari/IE 11/ChromiumEdge

Checklist

  • Checked in dark mode
  • Checked in mobile
  • Checked in IE11 and Firefox
    - [ ] Props have proper autodocs
    - [ ] Added documentation examples
  • Added or updated jest tests
  • Checked for breaking changes and labeled appropriately
  • Checked for accessibility including keyboard-only and screenreader modes
  • A changelog entry exists and is marked appropriately

@@ -71,6 +71,11 @@ body {

*:focus {
outline: none;

// sass-lint:disable no-vendor-prefixes
&::-moz-focus-inner {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Firefox doesn't use outline for focus states; this removes the border firefox gives all focused elements

Copy link
Contributor

@cchaos cchaos left a comment

Choose a reason for hiding this comment

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

The only visual regression I'm seeing is that the height of the whole control is now more than 20px probably from some extra browser default styles coming with <button>. Can you see if you can get this back down to 20px?

Before
Screen Shot 2019-08-02 at 10 01 58 AM

This PR
Screen Shot 2019-08-02 at 10 02 14 AM

src/components/form/switch/_switch.scss Outdated Show resolved Hide resolved
src/components/form/switch/_switch.scss Outdated Show resolved Hide resolved
src/components/form/switch/switch.js Outdated Show resolved Hide resolved
src/components/form/switch/switch.js Show resolved Hide resolved
Copy link
Contributor

@thompsongl thompsongl left a comment

Choose a reason for hiding this comment

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

Haven't tracked down why this happens, but in Firefox only:

Before:
Kapture 2019-08-02 at 14 03 39

After:
Kapture 2019-08-02 at 14 02 33

Lost some animation smoothness.

CHANGELOG.md Outdated
@@ -2,6 +2,10 @@

- Added `partial` glyph to `EuiIcon` ([#2152](https://github.com/elastic/eui/pull/2152))

**Bug fixes**
Copy link
Contributor

Choose a reason for hiding this comment

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

You'll need to move your entries to the master section at the top on the file.
(We're working on automating this somehow so it's not an annoyance in the future)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure I did correct still...

src/components/form/switch/switch.js Show resolved Hide resolved
@myasonik
Copy link
Contributor Author

myasonik commented Aug 5, 2019

@thompsongl Hmmm, it seems pretty smooth on my machine...

switch

@cchaos
Copy link
Contributor

cchaos commented Aug 5, 2019

@myasonik I think you might have forgotten to push your latest changes?

Copy link
Contributor

@cchaos cchaos left a comment

Choose a reason for hiding this comment

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

The style & SASS changes LGTM, but if we remove onChange for onToggle and cause this to be a breaking change, there's still work to do.

CHANGELOG.md Show resolved Hide resolved
src-docs/src/views/form_controls/switch.js Outdated Show resolved Hide resolved
src/components/form/switch/switch.js Show resolved Hide resolved
@timroes
Copy link
Contributor

timroes commented Aug 6, 2019

Is there a specific reason (I didn't find any comment about that) why onChange has been renamed to onToggle? This feels very unrelated to fixing the semantics of the underlying HTML element and also has the problem (despite deprecation), that we need to fix A LOT OF code in Kibana. Also having every control using the same change callback name had the nice side effect that you knew it was onChange and you don't need to dig into documentation, to figure out if it's onChange, onToggle, onChecked, etc. depending on the concrete type?

@myasonik
Copy link
Contributor Author

myasonik commented Aug 6, 2019

@timroes It was a bit talked about here.

Basically:

  1. Method name sounded more accurate
  2. Having different method names lets you at a glance know if it's the deprecated API or the new one
  3. Seems to give the cleanest deprecation flow (if using the old method name, shim the event object to give the expected checked attribute; else, use the new method signature)

I don't think anyone held any strong feelings on this though. So, if you think keeping the same method name is better, I can revert the name change. Would you shim the event all the time then? Or not do it at all?

@timroes
Copy link
Contributor

timroes commented Aug 6, 2019

Good question, I am also not strongly against renaming it, just wondering if we shouldn't then do a similar renaming for the other controls as well, so they are not using onChange (unless they are really input fields)? So if we would keep onChange I assume we should also keep the "shimmed" event. But I don't have too strong feeling in either direction, so I'll totally leave the decision to you.

@myasonik
Copy link
Contributor Author

myasonik commented Aug 6, 2019

@chandlerprall got any strong feelings?

I'm leaning towards leaving it how I currently have it (deprecated onChange with shimmed event object, new onToggle method).

Not sure what to do about other components though. Nothing right now but, in the future... 🤷‍♂

@chandlerprall
Copy link
Contributor

It definitely is nice to keep the form controls' API the same and expose onChange, but in this case I think that becomes disingenuous as the onChange for switch no longer matches the other form controls unless we always shim the checked prop onto the button, which doesn't seem like the right long-term choice.

Which brings up another point - the shimming of a checked onto the button won't enable backwards compatibility in TypeScript.

This PR updates EuiSwitchProps to ButtonHTMLAttributes<HTMLInputElement> & { but it should be ButtonHTMLAttributes<HTMLButtonElement> & {. With that additional change, accessing the change event's target.checked in a typescript file fails

Error:(10, 49) TS2339: Property 'checked' does not exist on type 'EventTarget & HTMLButtonElement'.

We would need to typedef the shim with

	  export type EuiSwitchProps = CommonProps &
	    Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'onChange'> & {
	      label?: ReactNode;
	      checked: boolean;
	      onChange?: (event: React.FormEvent<HTMLButtonElement & { checked: boolean }>) => void;
	      onToggle?: Function;
	      disabled?: boolean;
	      compressed?: boolean;
	    };

@chandlerprall
Copy link
Contributor

Alright, we discussed this in the design meeting and we're all leaning toward maintaining the better developer experience, which is keeping this as onChange with no deprecation.

This assumes:

  • All browsers are fine with setting checked to true/false on a button element
  • TypeScript defs in EUI can communicate this additional value correctly (see my previous comment)
  • React's synthetic event wrapping doesn't do anything weird to prevent this

@myasonik
Copy link
Contributor Author

OK, I've removed the breaking change and have left the shimed checked property.

I also changed the documentation to not actually use that property anymore though, instead relying on locally toggling the state, to quietly discourage its use. (Most implementations of swtich seem to do this anyway.)

@cchaos cchaos added deprecations Contains deprecations. Add them to the deprecations meta ticket after merge. and removed deprecations Contains deprecations. Add them to the deprecations meta ticket after merge. labels Aug 13, 2019
Copy link
Contributor

@cchaos cchaos left a comment

Choose a reason for hiding this comment

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

Styling lgtm

Copy link
Contributor

@thompsongl thompsongl left a comment

Choose a reason for hiding this comment

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

I'm still seeing the choppy animation in Firefox, but if no one else can reproduce, then everything looks good.

@myasonik myasonik merged commit 76e58de into elastic:master Aug 14, 2019
thompsongl added a commit to thompsongl/eui that referenced this pull request Aug 23, 2019
@thompsongl thompsongl mentioned this pull request Aug 23, 2019
1 task
thompsongl added a commit that referenced this pull request Aug 23, 2019
* Revert "Convert `EuiSwitch` to TS (#2243)"

This reverts commit 39dbcf6.

* Revert "Aligning switch semantics with aria role (#2193)"

This reverts commit 76e58de.

* CL
thompsongl added a commit that referenced this pull request Aug 23, 2019
* Revert "Convert `EuiSwitch` to TS (#2243)"

This reverts commit 39dbcf6.

* Revert "Aligning switch semantics with aria role (#2193)"

This reverts commit 76e58de.

* CL
thompsongl pushed a commit to thompsongl/eui that referenced this pull request Sep 10, 2019
* Removes FF's focus ring to match other browsers

* Aligning switch semantics with aria role
thompsongl added a commit to thompsongl/eui that referenced this pull request Sep 10, 2019
* Revert "Convert `EuiSwitch` to TS (elastic#2243)"

This reverts commit 39dbcf6.

* Revert "Aligning switch semantics with aria role (elastic#2193)"

This reverts commit 76e58de.

* CL
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.

5 participants