-
Notifications
You must be signed in to change notification settings - Fork 6.8k
fix(select):change calculateOverlayOffsetY to address offset for small lists #9885
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
Conversation
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.
Any new functionality has to have unit tests.
src/lib/select/select.ts
Outdated
@@ -1119,6 +1119,11 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit, | |||
const maxOptionsDisplayed = Math.floor(SELECT_PANEL_MAX_HEIGHT / itemHeight); | |||
let optionOffsetFromPanelTop: number; | |||
|
|||
// Disable offset for smaller lists by returning 0 as value to offset | |||
if (this._getItemCount() <= maxOptionsDisplayed) { |
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 goes against the Material design spec and I'm expecting it to break a lot of tests once we get to syncing it in. I think it's fine to have a functionality to disable it, but it should be an input that the consumer can opt-out of.
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 the feedback. I've updated the code to use a custom property to disable the offset only if the consumer chooses to do so by specifying it as a custom property. If nothing is specified, then the offset is enabled by default.
0c8bfb7
to
2846d51
Compare
2846d51
to
d87b1d7
Compare
src/lib/select/select.ts
Outdated
@@ -360,6 +360,9 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit, | |||
this._multiple = coerceBooleanProperty(value); | |||
} | |||
|
|||
/** Whether the user wants to disable the offset. */ | |||
@Input () disableOffset: 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.
Should be a boolean.
src/lib/select/select.ts
Outdated
@@ -1119,6 +1122,11 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit, | |||
const maxOptionsDisplayed = Math.floor(SELECT_PANEL_MAX_HEIGHT / itemHeight); | |||
let optionOffsetFromPanelTop: number; | |||
|
|||
// Disable offset for smaller lists by returning 0 as value to offset | |||
if (this.disableOffset == 'true') { |
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.
After changing it to a boolean, this should be if (this.disableOffset)
.
src/lib/select/select.ts
Outdated
@@ -360,6 +360,9 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit, | |||
this._multiple = coerceBooleanProperty(value); | |||
} | |||
|
|||
/** Whether the user wants to disable the offset. */ |
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'm not sure whether people looking at the documentation would know what offset this is referring to. What about calling it something like disableOptionCentering
?
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've made the changes you requested for the input:
- changed type to boolean
- changed name of the variable
- changed the if statement 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.
Note that this comment will end up on the docs site. Something along the lines of "Whether to center the active option over the trigger" would be clearer.
src/lib/select/select.ts
Outdated
@@ -1119,6 +1122,11 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit, | |||
const maxOptionsDisplayed = Math.floor(SELECT_PANEL_MAX_HEIGHT / itemHeight); | |||
let optionOffsetFromPanelTop: number; | |||
|
|||
// Disable offset for smaller lists by returning 0 as value to offset | |||
if (this.disableOffset == 'true') { | |||
return 0; |
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 new option still needs unit tests.
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've added a unit test with option centering disabled
along with a component for testing it. I was thinking of adding it to the 'positioning' tests, but didn't do so to make it easier to add other cases.
I've run gulp test
after adding it and the headless chrome returns all successful, but I'm not sure if there is a better way to test it.
src/lib/select/select.spec.ts
Outdated
<div [style.height.px]="heightBelow"></div> | ||
` | ||
}) | ||
class SelectWithoutOptionCentering { |
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 you trim this component down only to the functionality necessary to test the new option? Alternatively you should be able to re-use some of the other test components.
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've gone with trimming the component down and got rid of what I could. The @Input
and unit test description have also been updated.
src/lib/select/select.spec.ts
Outdated
formField = fixture.debugElement.query(By.css('mat-form-field')).nativeElement; | ||
})); | ||
|
||
it('should align the first option with trigger text if option centering is 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.
"Pizza" is the second option in this case. Also it may be clearer if it was something like it('should not align the active option with the trigger if centering is disabled')
.
src/lib/select/select.ts
Outdated
@@ -360,6 +360,9 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit, | |||
this._multiple = coerceBooleanProperty(value); | |||
} | |||
|
|||
/** Whether the user wants to disable the offset. */ |
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.
Note that this comment will end up on the docs site. Something along the lines of "Whether to center the active option over the trigger" would be clearer.
…late to trim uneeded parts
src/lib/select/select.ts
Outdated
@@ -360,6 +360,9 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit, | |||
this._multiple = coerceBooleanProperty(value); | |||
} | |||
|
|||
/** Whether to center the active option over the trigger. */ | |||
@Input () disableOptionCentering: boolean = false; |
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 you use coerceBooleanProperty()
for this? (see above for examples)
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 the suggestion! I've implemented it and it seems to make it easier for the user to customize now.
src/lib/select/select.ts
Outdated
@@ -1119,6 +1122,11 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit, | |||
const maxOptionsDisplayed = Math.floor(SELECT_PANEL_MAX_HEIGHT / itemHeight); | |||
let optionOffsetFromPanelTop: number; | |||
|
|||
// Disable offset for smaller lists by returning 0 as value to offset |
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 think this comment is out of date now ("smaller lists")
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.
Good to go once the final set of feedback is addressed.
src/lib/select/select.ts
Outdated
@@ -360,6 +360,9 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit, | |||
this._multiple = coerceBooleanProperty(value); | |||
} | |||
|
|||
/** Whether to center the active option over the trigger. */ | |||
@Input () disableOptionCentering: boolean = false; |
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 the extra space before @Input
.
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've updated it along with the changes @willshowell mentioned. It changes the way we use the new option so the unit test template has been adjusted accordingly.
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
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. |
Fixes #9751
Adds to the
_calculateOverlayOffsetY
function ofselect.ts
to disable the offset for lists when an option is already selected.Current implementation determines if the new functionality is enabled based on a new property
disableOptionCentering
. It is used by adding the textdisableOptionCentering
to the inside of the<mat-select>
tag like you would formultiple
.Example of usage:
list with offset:

list without offset:
