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
fix(picker-column): dynamically change options #27359
Conversation
Run & review this pull request in StackBlitz Codeflow. |
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 aside from one last tweak 👍 Thank you!
core/src/components/picker-column/test/dynamic-options/index.html
Outdated
Show resolved
Hide resolved
core/src/components/picker-column/test/dynamic-options/picker-column.e2e.ts
Outdated
Show resolved
Hide resolved
core/src/components/picker-column/test/dynamic-options/picker-column.e2e.ts
Outdated
Show resolved
Hide resolved
core/src/components/picker-column/test/dynamic-options/picker-column.e2e.ts
Outdated
Show resolved
Hide resolved
core/src/components/picker-column/test/dynamic-options/picker-column.e2e.ts
Outdated
Show resolved
Hide resolved
|
||
this.refresh(); | ||
componentDidUpdate() { | ||
// Options may have changed since last update. |
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.
// Options may have changed since last update. | |
// Options have changed since last update. |
If colDidChange
is true
then the columns definitely changed since the last render
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.
A few small comment/style things, but otherwise this is good to go. Great job on this!
// Options may have changed since last update. | ||
if (this.colDidChange) { | ||
// Animation must be disabled through the `onDomChange` parameter. | ||
// Otherwise, the recently added options will will render |
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.
// Otherwise, the recently added options will will render | |
// Otherwise, the recently added options will render |
@@ -74,21 +80,32 @@ export class PickerColumnCmp implements ComponentInterface { | |||
onEnd: (ev) => this.onEnd(ev), | |||
}); | |||
this.gesture.enable(); | |||
// Options have not been initialized yet | |||
// Animation must be disabled through the `noAnimate` flag | |||
// Otherwise, the options will will render |
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.
// Otherwise, the options will will render | |
// Otherwise, the options will render |
@@ -33,6 +33,12 @@ export class PickerColumnCmp implements ComponentInterface { | |||
private rafId?: ReturnType<typeof requestAnimationFrame>; | |||
private tmrId?: ReturnType<typeof setTimeout>; | |||
private noAnimate = true; | |||
// `colDidChange` is a flag that gets set when the column is changed | |||
// dynamically. When this flag is set, the column will refresh | |||
// to incorporate the new column data. |
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.
// to incorporate the new column data. | |
// after the component re-renders to incorporate the new column data. | |
// This is necessary because `this.refresh` queries for the option elements, | |
// so it needs to wait for the latest elements to be available in the DOM. |
@@ -132,6 +149,7 @@ export class PickerColumnCmp implements ComponentInterface { | |||
const scaleStr = `scale(${this.scaleFactor})`; | |||
|
|||
const children = this.optsEl.children; | |||
|
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.
@@ -185,6 +203,7 @@ export class PickerColumnCmp implements ComponentInterface { | |||
button.classList.remove(PICKER_OPT_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.
Issue number: resolves #21763
What is the current behavior?
Picker options do not render correctly when dynamically changed. It throws an error when the original options' length is no longer the same as the updated options' length. This is due to
refresh()
being called withthis.optsEl
having a stale list of children. The list doesn't get updated until the upcoming render.What is the new behavior?
The column will call
refresh()
when it detects the columns has changed. The call needs to be done afterthis.optsEl
gets updated with the correct number of children.componentShouldUpdate()
will check if options has changed -> re-renders with the updated options ->componentDidUpdate()
callsrefresh()
based oncomponentShouldUpdate()
The standalone test page has been updated to include a way to test this fix.
Does this introduce a breaking change?
Other information
It might be beneficial to review the component lifecycle.
Co-authored-by: liamdebeasi liamdebeasi@users.noreply.github.com