-
Notifications
You must be signed in to change notification settings - Fork 13.5k
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: integrate column-option into column #28622
Conversation
const dataIndex = activeElement.getAttribute('data-index'); | ||
|
||
/** | ||
* If no value it is | ||
* possible we hit one of the | ||
* empty padding columns. | ||
*/ | ||
if (dataIndex === null) { | ||
return; | ||
} | ||
|
||
const index = parseInt(dataIndex, 10); | ||
const selectedItem = this.items[index]; | ||
|
||
if (selectedItem.value !== this.value) { | ||
this.setValue(selectedItem.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.
Before, we were dealing with button
elements so we had to encode the button index so we could then find the associated item value. We don't need to do that with the option component since we can just look at the value
property directly.
@@ -325,8 +338,8 @@ export class PickerColumn implements ComponentInterface { | |||
} | |||
} | |||
|
|||
activeEl = activeElement; | |||
this.setPickerItemActiveState(activeElement, true); | |||
activeEl = newActiveElement; |
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 name change isn't needed to land this PR, but I couldn't immediately tell the different between activeEl
and activeElement
so I felt it best to rename.
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.
Thank you! This makes it easier to comprehend when skimming the code.
/** | ||
* This null check is important because activeEl | ||
* can be undefined but newActiveElement can be | ||
* null since we are using a querySelector. | ||
* newActiveElement !== activeEl would return true | ||
* below if newActiveElement was null but activeEl | ||
* was undefined. | ||
*/ | ||
if (newActiveElement === null || newActiveElement.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 considered making activeEl
null instead of undefined, but I decided against it. Array.prototype.find
returns undefined
if an array option was not found, and querySelector
returns null
if the element was not found in the DOM. I decided it would be better to add this comment highlighting the importance of the newActiveElement === null
check instead of having the other methods return a value they were not designed to return.
const findItem = items.find((item) => item.value === value && item.disabled !== true); | ||
if (findItem) { | ||
this.ionChange.emit(findItem); | ||
} |
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.
Not needed anymore. We could have this filter through the existing ion-picker-column-option
elements, but none of our other grouped components do this (accordion, radio group, etc)
componentDidLoad() { | ||
const parentPickerColumn = this.el.closest('ion-picker-column'); | ||
if (parentPickerColumn !== null && this.value === parentPickerColumn.value) { | ||
parentPickerColumn.scrollActiveItemIntoView(); | ||
} | ||
} |
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 new behavior. With the internal picker, the options were part of ion-picker-column-internal
, so we knew exactly when the options were loaded. With the ion-picker-column-option
approach, these options can be loaded at any time (such as in an *ngIf
), so we need the options to tell the column when it is ready to be scrolled into view.
*/ | ||
configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => { | ||
test.describe(title('picker-column: disabled rendering'), () => { | ||
test('should not have visual regressions', async ({ page }) => { |
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 checking that the column options are rendered correctly when disabled. I already did this in #28621, so this test is not needed.
/** | ||
* This behavior does not vary across modes/directions. | ||
*/ | ||
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => { | ||
test.describe(title('picker-column: disabled items'), () => { | ||
// TODO FW-5580 move this to a spec test in picker-column-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.
This is much easier to test using a spec test now, so I'd like to update this in a future PR.
|
||
expect(await pickerItems.count()).toBe(3); | ||
}); | ||
// TODO FW-5580 move this to a spec test in picker-column-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.
This is much easier to test using a spec test now, so I'd like to update this in a future PR.
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => { | ||
test.describe(title('picker-column: disabled column'), () => { | ||
test.describe.skip(title('picker-column: disabled column'), () => { |
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 will be handled in a future PR
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => { | ||
test.describe(title('picker: keyboard entry'), () => { | ||
test.describe.skip(title('picker: keyboard entry'), () => { |
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 will be handled in a future PR
@@ -53,31 +53,36 @@ <h2>Even items disabled</h2> | |||
<div class="grid-item"> | |||
<h2>Column disabled</h2> | |||
<ion-picker> | |||
<ion-picker-column id="column-disabled" value="11" disabled></ion-picker-column> |
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 value here was bound as a string, but the value on each option was bound as a number. This should have always been failing, but not sure why it wasn't in the past.
Co-authored-by: Sean Perkins <[email protected]>
core/src/components/picker-column-option/picker-column-option.tsx
Outdated
Show resolved
Hide resolved
@@ -325,8 +338,8 @@ export class PickerColumn implements ComponentInterface { | |||
} | |||
} | |||
|
|||
activeEl = activeElement; | |||
this.setPickerItemActiveState(activeElement, true); | |||
activeEl = newActiveElement; |
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.
Thank you! This makes it easier to comprehend when skimming the code.
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, smooth on click also works
Spoke with Sean offline and he's good with merging. |
Issue number: Internal
What is the current behavior?
We'd like to introduce a new API to the picker column to allow developers to manipulate the picker options right in the DOM. Currently developers need to pass an object which is quite cumbersome as you need to re-pass that object anytime you want to change a single option.
What is the new behavior?
ion-picker-column
now usesion-picker-column-option
for displaying options in a columnThere are a few things missing from this PR. I plan to address this separately and have disabled their tests for now:
Notes to reviewers:
Does this introduce a breaking change?
The shadow parts on the picker column options have been removed since they are in the light DOM now. The
wheel-item
andactive
parts remain when targeting the wheel inside ofion-datetime
.Other information