-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
refactor(select): replace menu with native html select #2462
Conversation
packages/mdc-select/index.js
Outdated
} | ||
|
||
nameditem(key) { |
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.
may want to reimplement namedItem
…al-components/material-components-web into refactor/select/use-native-select
packages/mdc-select/README.md
Outdated
</div> | ||
``` | ||
|
||
Use the `<option disabled selected/>` element as a way to display the select having no value. |
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.
Say what?
packages/mdc-select/README.md
Outdated
|
||
| Method Signature | Description | | ||
| --- | --- | | ||
| `item(index: number) => HTMLElement?` | Analogous to `HTMLSelectElement.prototype.item`. Returns the option at the specified index, or `null` if the index is out of bounds. } | ||
| `nameditem(key: string) => HTMLElement?` | Analogous to `HTMLSelectElement.prototype.nameditem`. Returns the options either whose `id` equals the given `key`, or whose `name` attribute equals the given `key`. Returns `null` if no item with an `id` or `name` attribute of the specified key is found. | | ||
| `initialSyncWithDOM() => void` | Syncs the component with the current state of the HTML markup. | |
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.
This is a method on all components, you don't need to document it
packages/mdc-select/README.md
Outdated
| `mdc-list-divider` | A divider. | | ||
|
||
It is advised that dividers also set `role="presentation"` to disable selection and not cloud accessibility. | ||
| `mdc-select__option` | A select option. | |
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.
Is this a necessary class?
…ethods on foundation
…al-components/material-components-web into refactor/select/use-native-select
Codecov Report
@@ Coverage Diff @@
## master #2462 +/- ##
==========================================
- Coverage 98.9% 98.87% -0.04%
==========================================
Files 102 102
Lines 4218 4073 -145
Branches 528 510 -18
==========================================
- Hits 4172 4027 -145
Misses 46 46
Continue to review full report at Codecov.
|
packages/mdc-select/mdc-select.scss
Outdated
|
||
border-bottom-width: 1px; | ||
border-bottom-style: dotted; | ||
opacity: .38; | ||
cursor: default; | ||
pointer-events: none; | ||
// Imitate native disabled functionality | ||
user-select: none; | ||
|
||
.mdc-select__bottom-line { | ||
display: none; | ||
} | ||
} | ||
|
||
// postcss-bem-linter: end |
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 still need this?
packages/mdc-select/index.js
Outdated
return this.root_.querySelectorAll('[aria-selected]'); | ||
// In an array because HTML spec also returns an array. | ||
// Cannot access HTMLSelectElement.selectedIndex since it is not supported by IE11. | ||
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLSelectElement/selectedIndex |
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.
selectedIndex
-> selectedOptions
https://developer.mozilla.org/en-US/docs/Web/API/HTMLSelectElement/selectedIndex
-> https://developer.mozilla.org/en-US/docs/Web/API/HTMLSelectElement/selectedOptions
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.
First round of review. Didn't bother reviewing tests because I have some adapter API suggestions first.
demos/select.html
Outdated
</div> | ||
</section> | ||
</section> | ||
<section class="example"> | ||
<h2 class="mdc-typography--title">OptGroup JS Component</h2> |
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.
Re-word to "MDC Select with optgroups"
packages/mdc-select/README.md
Outdated
option with `aria-selected`. This will ensure that the label moves out of the way of the select's value | ||
and prevents a Flash Of Un-styled Content (**FOUC**). | ||
option with the `selected` attribute. This will ensure that the label moves out | ||
of the way of the select's value and prevents a Flash Of Un-styled Content (**FOUC**). |
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.
While we're here, remove the - from unstyled
packages/mdc-select/README.md
Outdated
</div> | ||
``` | ||
|
||
#### Select with floating label as the placeholder | ||
|
||
Use the `<option disabled selected hidden/>` element as a way to display the select having no value. |
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.
hidden
seems to have issues even in some browsers that support it, e.g. Edge and Safari where it leaves an empty space in the menu because of the hidden option. Between that and it not being supported by IE at all, I'd be inclined to leave it out...
Also, I'm not sure why you're saying to add the float-above class here? If the select initially has "no value", you would not want the float-above modifier (and our demo seems to match that).
Aside from that, I think this paragraph could use some re-wording anyway:
By default, `<select>` elements will select their first enabled option. In order to initially display a placeholder
instead, add an initial `<option>` element with the `disabled` *and* `selected` attributes set, and with `value` set to `""`.
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 was saying to add float-above if you want a placeholder instead of using the label, but the way I worded it is confusing and this might not be the place so I'll remove. Should I also remove hidden
from the demos as well?
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.
Yes, I think I commented on the line in the demo page too.
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.
Also, not sure what you mean regarding wanting a placeholder instead of using the label... the placeholder
attribute is not a thing for native select
(since select
normally always has an option selected)
packages/mdc-select/README.md
Outdated
if you do use this option as a placeholder to add the `mdc-select__label--float-above` class. Refer to [pre-selected option](#select-with-pre-selected-option). Also note that not all browsers respect the `hidden` attribute (ie. IE11). | ||
|
||
```html | ||
<option value="" disabled selected hidden></option> |
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.
Remove hidden
as per above comment
packages/mdc-select/README.md
Outdated
#### Disabled select | ||
|
||
Add the `mdc-select--disabled` class to the `mdc-select` element. The 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.
I would re-word this to always recommend also setting the disabled
attribute on the select element, again to prevent FOUC (and more importantly to prevent users from interacting with the select if JS loads slowly). The initialSyncWithDOM stuff should be more of a coincidental implementation detail that isn't needed here.
Also, throughout the readme, don't refer to <select>
and <option>
with slashes... they always have matching closing tags, so this just seems unnatural.
packages/mdc-select/mdc-select.scss
Outdated
display: flex; | ||
position: relative; | ||
flex-grow: 1; | ||
&::-ms-expand { |
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.
Above this, also add @include mdc-typography-base;
to force consistent font (browsers like to reset font on inputs, and the box variant already resolves this by way of including a specific typography scale which itself includes base)
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.
This still needs to be resolved; non-box selects are still using the browser's default input font
packages/mdc-select/index.js
Outdated
|
||
this.ripple = new MDCRipple(this.surface_); | ||
this.ripple = new MDCRipple(this.root_); |
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.
Two issues here:
- We probably want to do something like what we do with checkbox/radio/text-field to forward the ripple component's event handlers to the select element. This should make activation work when pressing space, and should make focus styles work via ripple JS.
- We should only instantiate ripple if we're using the box variant (text field should have similar logic to check for a modifier class).
packages/mdc-select/mdc-select.scss
Outdated
@@ -114,14 +109,15 @@ | |||
background-position: left 10px center; | |||
} | |||
|
|||
.mdc-select__surface { | |||
.mdc-select__surface, |
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.
Since this element is no longer the ripple surface, we might want to consider renaming it... e.g. checkbox has __native-control
for this.
(We'd want to change variable names in JS too)
packages/mdc-select/mdc-select.scss
Outdated
@@ -27,12 +28,15 @@ | |||
// postcss-bem-linter: define select | |||
.mdc-select { | |||
@include mdc-typography-base; | |||
@include mdc-states; |
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.
This should be in --box
styles where the other ripple mixins are used. It doesn't make sense for this to apply to anything without those styles.
When you move it, change it to: @include mdc-states(text-primary-on-light, $has-nested-focusable-element: true);
This will make the ripple match the ink color, and make focus shade work properly given the nested select element, even when ripple JS isn't used (I know, right now we require JS, but this seems like the more technically correct thing to do esp. if there is ever hope of CSS-only down the road)
packages/mdc-select/mdc-select.scss
Outdated
@@ -27,12 +28,15 @@ | |||
// postcss-bem-linter: define select | |||
.mdc-select { | |||
@include mdc-typography-base; | |||
@include mdc-states; | |||
|
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.
We might want to go ahead and remove the following @each
which is applying letter-spacing typography styles, since IIUC we're probably removing that property from typography anyway, and this might be hard to catch when we do a sweep later... @lynnjepsen what do you think?
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.
Looking good RE APIs; reviewed tests this time too. I think the arrow location hasn't been fixed for non-box yet?
demos/select.html
Outdated
<div id="box-js-select" class="mdc-select mdc-select--box"> | ||
<select class="mdc-select__native-control"> | ||
<option value="" disabled selected></option> | ||
<option value="fruit-roll-ups1"> |
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.
These don't need "1"s on the values anymore, thanks to us no longer awkwardly using IDs as values. (Don't forget to update the value set in the JS below too)
demos/select.html
Outdated
</div> | ||
<div id="js-pre-selected" class="mdc-select"> | ||
<select class="mdc-select__native-control"> | ||
<option value="fruit-roll-ups2" selected> |
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.
You can remove the numbers on these values too now.
demos/select.html
Outdated
<div id="optgroup-js-select" class="mdc-select"> | ||
<select class="mdc-select__native-control"> | ||
<optgroup label="Meats"> | ||
<option value="hot-dog">Steak</option> |
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.
hot-dog -> steak?
demos/select.html
Outdated
<option value="hamburger">Hamburger</option> | ||
</optgroup> | ||
<optgroup label="Vegetables"> | ||
<option value="beets">Beets</option> |
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.
Nit: make this singular to match other entries
packages/mdc-select/mdc-select.scss
Outdated
white-space: nowrap; | ||
cursor: pointer; | ||
appearance: none; |
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.
Is the overflow: hidden
below this needed? It was needed for __surface
before because that's what contained the ripple, but that's been moved.
packages/mdc-select/README.md
Outdated
| `getSelectedIndex() => number` | Returns the selected index of the `<select>` element. | | ||
| `setSelectedIndex(index: number) => void` | Sets the select's selectedValue to the option found at the provided index. If the index is out of the select's range, it will default to -1. | | ||
| `getValue() => string` | Returns the value selected on the `<select>` element. | | ||
| `setValue(value: string) => void` | Sets the select's value. If no option has the provided value, it sets `value` to empty string. | |
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.
Reduce this to: Sets the value of the <select>
element.
(The rest is re-documenting native behavior.)
packages/mdc-select/README.md
Outdated
|
||
| Method Signature | Description | | ||
| --- | --- | | ||
| `setValue(value: string) => void` | Sets the select's value. If value is not found within list of options, it will set it to empty string. | |
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.
Similar to above, reduce description: Sets the value of the component.
</div> | ||
``` | ||
|
||
#### Select with floating label as the placeholder | ||
|
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.
Extra newlines here and before the next heading? Just need one empty line
packages/mdc-select/mdc-select.scss
Outdated
display: flex; | ||
position: relative; | ||
flex-grow: 1; | ||
&::-ms-expand { |
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.
This still needs to be resolved; non-box selects are still using the browser's default input font
packages/mdc-select/index.js
Outdated
|
||
this.ripple = new MDCRipple(this.surface_); | ||
if (this.root_.classList.contains(cssClasses.BOX)) { | ||
this.ripple = new MDCRipple(this.root_); |
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.
Only one of my two previous comments was resolved. Here's the other one:
We probably want to do something like what we do with checkbox/radio/text-field to forward the ripple component's event handlers to the select element. This should make activation work when pressing space, and should make focus styles work via ripple JS.
Specifically, I'm talking about e.g. this:
material-components-web/packages/mdc-checkbox/index.js
Lines 64 to 65 in 3f23821
registerInteractionHandler: (type, handler) => this.nativeCb_.addEventListener(type, handler), | |
deregisterInteractionHandler: (type, handler) => this.nativeCb_.removeEventListener(type, handler), |
…ial-components/material-components-web into refactor/select/use-native-select
* Simplify ripple tests * Don't worry about wrapping ripple activation * README fixes
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 applied one last round of edits this morning; I think this is good, but you might want to look at my changes.
This should probably be feat(select) since it does affect APIs and functionality, and we need something like BREAKING CHANGE: The template and adapter APIs have changed to take advantage of the native select element; see the MDC Select README for more information.
These review points have been resolved
white-space: nowrap; | ||
overflow: hidden; | ||
cursor: pointer; | ||
appearance: none; |
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.
FYI, across the code base the prefixed version of appearance is used
-moz-appearance: none;
-webkit-appearance: none;
According to https://caniuse.com/#search=appearance the unprefixed version has very little support currently
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 vendor prefixes are added automatically by autoprefixer when we build releases (and you are encouraged to do the same if you have your own Sass workflow). I have noticed that we have a few components using the vendor prefixes directly, which we should probably fix to use the non-prefixed version that will be picked up by autoprefixer.
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 see, thanks for clarifying @kfranqueiro
Is there a documentation for how one is supposed to use @material/*
scss as and then apply postcss? Since postcss supports plugins/etc I am not sure which setup is the one mcw rely on.
In my case we compile a css with @material/*
mixins to build a custom theme + some overrides.
Change as per material-components-web v0.34.1. reference: material-components/material-components-web#2462 BREAKING CHANGE: - The template and adapter APIs have changed to take advantage of the native select element; see the MDC Select README for more information. - Removed mdc-select-item component. Replace with HTML5's native option element.
fixes #2399