-
Notifications
You must be signed in to change notification settings - Fork 6.7k
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
feat(material-experimental/mdc-slide-toggle): switch to non-deprecated styles #23143
Conversation
0405b0e
to
3b2e7cb
Compare
scripts/check-mdc-tests-config.ts
Outdated
// The MDC implementation uses a `button` instead of an `input` which can't be required. | ||
'should forward the required attribute', | ||
'should prevent the form from submit when being required', | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add Angular's required validation manually? We support required
on MatSelect
which isn't a native control
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only thing we were using the required
input for was aria-required
which doesn't make sense on a button
. We also have the MatSlideToggleRequiredValidator
directive which matches on it, but we don't actually need an input for it to be picked up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
role="switch"
does support aria-required
, though, so we should still support that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to aXe it isn't supported so I had to leave it out, otherwise it might've broken the g3 aXe check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aha, aria-required
is supported in ARIA 1.2, but not in ARIA 1.1. It seems like axe is out of date. I sent an email to Google's a11y list to see if anyone has a recommended here. My hunch is that axe should be updated to support this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The feedback I got was to focus on how it actually works in the various assistive tech, so we should just test it with a few screen-readers and see how it works. I tested having aria-required
on the <button>
and it worked as expected on VoiceOver and NVDA- I think we should try to keep it and update the axe configuration to accept it.
|
||
// Generates all color mapping for the properties that only change based on the theme. | ||
@function _get-theme-base-map($is-dark) { | ||
$on-surface: if($is-dark, mdc-color-palette.$grey-100, mdc-color-palette.$grey-800); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add a comment that explains where these color choices come from? E.g. why is $on-surface
gray-100/gray-800?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this is the part where I had to make some assumptions. The light theme values come from MDC's $light-theme
variable one-to-one, but since MDC didn't provide a dark theme, I had to come up with the values myself. I did try to follow a pattern (e.g. 800 and 100 are on different ends of the palette), but it's not foolproof.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I chatted with the MDC team about the status/plan here. Summary is:
- For the new version of Material Design, there will be a set of token values OSS we can use, but they're not ready yet.
- We have a set of token values internally for Google's specific brand configuration, but those aren't public
- The MDC team is picking as reasonable values as they can for 2018-era Material Design (M2) tokens, but they didn't do dark theme values since we're the only ones using them, so it's reasonable for us to decide them on our own.
The tokens are split into two parts: system tokens (used across multiple components) and component-specific tokens. I think we should create a Sass file in material/core for the baseline token values, and then create a another file per component with the tokens for that specific spec version. So, something like
├── material/core/theming
│ ├── _system-tokens-2018.scss
├── material/slide-toggle
│ ├── _slide-toggle-tokens-2018.scss
We should make sure to comment which values we're just picking ourselves and which we're sourcing from somewhere else.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we know which ones are system tokens and which ones are slide toggle-specific? I can make some reasonable guesses, but it would be better if there was a list.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The format is a little rough, but this is the stuff currently considered system styles that we care about (there was also some shape stuff that we don't care about yet)
/** COLOR */// Background
$background;// Error
$error;// Error state content
$error-state-content;// Error state layer
$error-state-layer;// Hairline
$hairline;// Inverse on surface
$inverse-on-surface;// Inverse primary
$inverse-primary;// Inverse primary state content
$inverse-primary-state-content;// Inverse primary state layer
$inverse-primary-state-layer;// Inverse surface
$inverse-surface;// On background
$on-background;// On error
$on-error;// On error state content
$on-error-state-content;// On error state layer
$on-error-state-layer;// On primary
$on-primary;// On primary state content
$on-primary-state-content;// On primary state layer
$on-primary-state-layer;// On secondary
$on-secondary;// On secondary state content
$on-secondary-state-content;// On secondary state layer
$on-secondary-state-layer;// On surface
$on-surface;// On surface state content
$on-surface-state-content;// On surface state layer
$on-surface-state-layer;// On surface variant
$on-surface-variant;// Primary
$primary;// Primary state content
$primary-state-content;// Primary state layer
$primary-state-layer;// Primary variant
$primary-variant;// Secondary
$secondary;// Secondary variant
$secondary-variant;// Shadow color
$shadow;// Surface
$surface;// Textfield error
$textfield-error;// Textfield hairline
$textfield-hairline;// Textfield on surface variant
$textfield-on-surface-variant;// Textfield primary
$textfield-primary;// Textfield state layer
$textfield-state-layer;// Textfield surface
$textfield-surface;/** ANIMATION */
// Casual duration
$duration-long1;// Slow duration
$duration-long2;// Quick duration
$duration-medium1;// Standard duration
$duration-medium2;// Flash duration
$duration-short1;// Rapid duration
$duration-short2;// Accelerated easing (in)
$easing-accelerated;// Decelerated easing (out)
$easing-decelerated;// Emphasized
$easing-emphasized;// Linear easing
$easing-linear;// Standard easing (in and out)
$easing-standard;/** TYPOGRAPHY */
// Body 1
$body1: (
font-family,
font-size,
font-weight,
letter-spacing,
line-height,
text-transform,
);// Body 1 font name
$body1-font;// Body 1 line height
$body1-line-height;// Body 1 font size
$body1-size;// Body 1 font tracking
$body1-tracking;// Body 1 font weight
$body1-weight;// Body 2
$body2: (
font-family,
font-size,
font-weight,
letter-spacing,
line-height,
text-transform,
);// Body 2 font name
$body2-font;// Body 2 line height
$body2-line-height;// Body 2 font size
$body2-size;// Body 2 font tracking
$body2-tracking;// Body 2 font weight
$body2-weight;// Button
$button: (
font-family,
font-size,
font-weight,
letter-spacing,
line-height,
text-transform,
);// Button font name
$button-font;// Button line height
$button-line-height;// Button font size
$button-size;// Button font tracking
$button-tracking;// Button font weight
$button-weight;// Caption
$caption: (
font-family,
font-size,
font-weight,
letter-spacing,
line-height,
text-transform,
);// Caption font name
$caption-font;// Caption line height
$caption-line-height;// Caption font size
$caption-size;// Caption font tracking
$caption-tracking;// Caption font weight
$caption-weight;// Display 1
$display1: (
font-family,
font-size,
font-weight,
letter-spacing,
line-height,
text-transform,
);// Display 1 font name
$display1-font;// Display 1 line height
$display1-line-height;// Display 1 font size
$display1-size;// Display 1 font tracking
$display1-tracking;// Display 1 font weight
$display1-weight;// Display 2
$display2: (
font-family,
font-size,
font-weight,
letter-spacing,
line-height,
text-transform,
);// Display 2 font name
$display2-font;// Display 2 line height
$display2-line-height;// Display 2 font size
$display2-size;// Display 2 font tracking
$display2-tracking;// Display 2 font weight
$display2-weight;// Display 3
$display3: (
font-family,
font-size,
font-weight,
letter-spacing,
line-height,
text-transform,
);// Display 3 font name
$display3-font;// Display 3 line height
$display3-line-height;// Display 3 font size
$display3-size;// Display 3 font tracking
$display3-tracking;// Display 3 font weight
$display3-weight;// Headline 1
$headline1: (
font-family,
font-size,
font-weight,
letter-spacing,
line-height,
text-transform,
);// Headline 1 font name
$headline1-font;// Headline 1 line height
$headline1-line-height;// Headline 1 font size
$headline1-size;// Headline 1 font tracking
$headline1-tracking;// Headline 1 font weight
$headline1-weight;// Headline 2
$headline2: (
font-family,
font-size,
font-weight,
letter-spacing,
line-height,
text-transform,
);// Headline 2 font name
$headline2-font;// Headline 2 line height
$headline2-line-height;// Headline 2 font size
$headline2-size;// Headline 2 font tracking
$headline2-tracking;// Headline 2 font weight
$headline2-weight;// Headline 3
$headline3: (
font-family,
font-size,
font-weight,
letter-spacing,
line-height,
text-transform,
);// Headline 3 font name
$headline3-font;// Headline 3 line height
$headline3-line-height;// Headline 3 font size
$headline3-size;// Headline 3 font tracking
$headline3-tracking;// Headline 3 font weight
$headline3-weight;// Headline 4
$headline4: (
font-family,
font-size,
font-weight,
letter-spacing,
line-height,
text-transform,
);// Headline 4 font name
$headline4-font;// Headline 4 line height
$headline4-line-height;// Headline 4 font size
$headline4-size;// Headline 4 font tracking
$headline4-tracking;// Headline 4 font weight
$headline4-weight;// Headline 5
$headline5: (
font-family,
font-size,
font-weight,
letter-spacing,
line-height,
text-transform,
);// Headline 5 font name
$headline5-font;// Headline 5 line height
$headline5-line-height;// Headline 5 font size
$headline5-size;// Headline 5 font tracking
$headline5-tracking;// Headline 5 font weight
$headline5-weight;// Headline 6
$headline6: (
font-family,
font-size,
font-weight,
letter-spacing,
line-height,
text-transform,
);// Headline 6 font name
$headline6-font;// Headline 6 line height
$headline6-line-height;// Headline 6 font size
$headline6-size;// Headline 6 font tracking
$headline6-tracking;// Headline 6 font weight
$headline6-weight;// Overline
$overline: (
font-family,
font-size,
font-weight,
letter-spacing,
line-height,
text-transform,
);// Overline font name
$overline-font;// Overline line height
$overline-line-height;// Overline font size
$overline-size;// Overline text transform
$overline-text-transform;// Overline font tracking
$overline-tracking;// Overline font weight
$overline-weight;// Subhead 1
$subhead1: (
font-family,
font-size,
font-weight,
letter-spacing,
line-height,
text-transform,
);// Subhead 1 font name
$subhead1-font;// Subhead 1 line height
$subhead1-line-height;// Subhead 1 font size
$subhead1-size;// Subhead 1 font tracking
$subhead1-tracking;// Subhead 1 font weight
$subhead1-weight;// Subhead 2
$subhead2: (
font-family,
font-size,
font-weight,
letter-spacing,
line-height,
text-transform,
);// Subhead 2 font name
$subhead2-font;// Subhead 2 line height
$subhead2-line-height;// Subhead 2 font size
$subhead2-size;// Subhead 2 font tracking
$subhead2-tracking;// Subhead 2 font weight
$subhead2-weight;// Subtitle 1
$subtitle1: (
font-family,
font-size,
font-weight,
letter-spacing,
line-height,
text-transform,
);// Subtitle 1 font name
$subtitle1-font;// Subtitle 1 line height
$subtitle1-line-height;// Subtitle 1 font size
$subtitle1-size;// Subtitle 1 font tracking
$subtitle1-tracking;// Subtitle 1 font weight
$subtitle1-weight;// Subtitle 2
$subtitle2: (
font-family,
font-size,
font-weight,
letter-spacing,
line-height,
text-transform,
);// Subtitle 2 font name
$subtitle2-font;// Subtitle 2 line height
$subtitle2-line-height;// Subtitle 2 font size
$subtitle2-size;// Subtitle 2 font tracking
$subtitle2-tracking;// Subtitle 2 font weight
$subtitle2-weight;/** ELEVATION */
// 0
$level0;// +1
$level1;// +2
$level2;// +3
$level3;// +4
$level4;// +5
$level5;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for listing it out. Since this PR is pretty large already, would it be ok if I added these in a follow-up?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I think that's reasonable, I just want to make sure we do this before adding another component on top of the tokens system
src/material-experimental/mdc-slide-toggle/_slide-toggle-theme.scss
Outdated
Show resolved
Hide resolved
src/material-experimental/mdc-slide-toggle/_slide-toggle-theme.scss
Outdated
Show resolved
Hide resolved
src/material-experimental/mdc-slide-toggle/_slide-toggle-theme.scss
Outdated
Show resolved
Hide resolved
src/material-experimental/mdc-slide-toggle/_slide-toggle-theme.scss
Outdated
Show resolved
Hide resolved
} | ||
|
||
// Even though we have a `label` element with a `for` pointing to the button, we need the | ||
// `aria-labelledby`, because the button gets flagged as not having a label by tools like axe. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be worth filing an issue with axe
d6d2806
to
8f10f50
Compare
src/material-experimental/mdc-slide-toggle/_slide-toggle-theme.scss
Outdated
Show resolved
Hide resolved
8f10f50
to
83ef5af
Compare
All of the feedback should be addressed now. I'll wait for a green master build before rebasing. |
Good to go now. |
1e3548a
to
300cedb
Compare
scripts/check-mdc-tests-config.ts
Outdated
// The MDC implementation uses a `button` instead of an `input` which can't be required. | ||
'should forward the required attribute', | ||
'should prevent the form from submit when being required', | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The feedback I got was to focus on how it actually works in the various assistive tech, so we should just test it with a few screen-readers and see how it works. I tested having aria-required
on the <button>
and it worked as expected on VoiceOver and NVDA- I think we should try to keep it and update the axe configuration to accept it.
|
||
// Generates all color mapping for the properties that only change based on the theme. | ||
@function _get-theme-base-map($is-dark) { | ||
$on-surface: if($is-dark, mdc-color-palette.$grey-100, mdc-color-palette.$grey-800); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I think that's reasonable, I just want to make sure we do this before adding another component on top of the tokens system
[class.mdc-switch--selected]="checked" | ||
[class.mdc-switch--unselected]="!checked" | ||
[tabIndex]="tabIndex" | ||
[disabled]="disabled" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I tested the demo (looking at aria-required), I was able to toggle the disabled slide-toggles with the keyboard.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just tried it and I couldn't reproduce. Are you sure that you weren't interacting with the top slide toggle which also changes the value of the disabled one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh, I see what happened. With VoiceOver on, screen-reader navigation moved onto the disabled toggle, but browser focus stayed on the enabled one. Nvm.
300cedb
to
0855875
Compare
I've added |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
c3ecae0
to
eb14fa3
Compare
…d styles Switches the MDC-based slide toggle to the non-deprecated MDC styles. Notable changes: * New markup which uses a `button` instead of an `input` for the button. * New icons inside the slide toggle's thumb. Technically we could opt out of them, but I think that they look better and they help with accessibility for color-blind users. * New theming system that uses a flat list of variables. There is a fallback for IE11, but I opted not to include it for now, because of the upcoming deprecation and the fact that the component is in experimental. * The component has some slightly different colors and it supports more states (e.g. hover). * Due to the switch from `input` to `button`, the `required` input is basically a noop now.
eb14fa3
to
eeedcf8
Compare
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
Switches the MDC-based slide toggle to the non-deprecated MDC styles.
Notable changes:
button
instead of aninput
for the interaction.input
tobutton
, therequired
input is basically a noop now.Here's what it looks like now: