-
Notifications
You must be signed in to change notification settings - Fork 81
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
allow kselect to extend outside of kmodal #429
allow kselect to extend outside of kmodal #429
Conversation
…address issue of dropdown menu being trapped inside modal
…ng dropdown, dropdown rendering above input, and other observed buggy behavior
1775d54
to
afb762d
Compare
…lf whether it is inside a modal
Thank you @thanksameeelian, also for helpful implementation notes. Sorry to see it wasn't as simple as only removing overflows in all cases, but I think you resolved it well. The strategy to only apply updates to KModal and KSelect when they're used together makes sense in this case to me and I think it can prevent regressions of modals and selects in all products. Unless someone else gets to code sooner, I will review it in the next work day or two in more detail. For now, reading the description and skimming briefly through changes it's looking to be a good direction to me. @jredrejo How to best test changes in KDP? Would it be possible to do it before we merge this PR? For testing a KDS PR in Kolibri, we usually open a temporary draft Kolibri PR with an updated package.json pointing to the last commit of the corresponding KDS pull request and do testing on that Kolibri branch. However, I think that KDP gets KDS through Kolibri somehow due to being a Kolibri plugin, so I don't know how to approach it. |
the easiest way, if possible, would be replacing current Kselect in KDP by this one and check how the date picker behaves. I don't know if that replacing is achievable. I'm all ears in case you have hints |
I've tried to use this KSelect and KModal in current KDP and I haven't been able after trying several approaches:
Then:
I have not tried to install kolibri 0.16 because it'll likely break both the backend and the frontend (and probably will leave my db in an unstable state). |
lib/KSelect/KeenUiSelect.vue
Outdated
@@ -552,6 +553,10 @@ | |||
break; | |||
} | |||
} | |||
|
|||
// if located within KModal, special styles will be applied | |||
const kModalCheck = document.getElementsByClassName('modal'); |
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 update this check to something like:
this.$el.querySelect(".modal .ui-select") === this.$el
to be more precise that this ui-select is inside a modal.
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! i'll look into implementing something along these lines tomorrow morning!
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.
@rtibbles i ended up following the spirit of your advice with querySelectorAll()
after realizing that if there were multiple KSelect
s located within a single modal, this.isInsideModal
would only correctly register as true
for the first KSelect
because when querySelector
was called by the other KSelect
s it would grab the first KSelect
it found and stop looking, so the comparison would fail and the other KSelect
s would lack their intended styling.
unfortunately, while checking the intricacies of these components' behavior when a KModal
contains 2+ KSelect
s I discovered a recurrence some minor undesirable modal-elongating behavior that I already built out conditional code to avoid in the case of there being just 1 KSelect
, but accidentally didn't account for how much more complex the relationship between the height properties would become once there were multiple KSelect
s. i've been fiddling around with it frustratingly but haven't yet gotten it working as desired, and am not sure how much brain power is worth dedicating to that case.
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.
Hrm - interesting. The additional height only appears when the value is selected in the second one? Or it only happens when a value is selected in both?
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 appears once a value is selected in both -- the code i added to try to circumvent this problem is catching it the first time (whichever one is opened first), but because it was hacky it's not catching a second (and subsequent...) ones correctly.
my understanding is that this happens in general because the existing function looks at the scrollHeight of content to determine the height of the modal, and once the dropdown is opened it grabs its length as the newest scrollHeight and makes adjustments. my hack was basically just skipping 1 round of this calculation if a KSelect
was found in a modal, but a bit more convoluted than that.
it would be cool if we could just like...freeze the modal height forever if we knew there were KSelect
s inside, except a specific dropdown selection, depending on what it was, could result in a change to the rendered content so i figured it needed to remain dynamic
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 i think maybe the answer is patching up the updateContentSectionStyle()
calculation in a slightly different way than i have been? (/trying to work on making sure that scrollheight, etc in that function are targeting exactly what we expect and want them to be targeting)
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.
@jredrejo Thank you for going through the trouble. I will find time to have a look at the KDP code and see if I get an idea, even though after reading about your attempt, I don't expect that to be successful since I think I'd approach it the same way you did. From your message, it sounds like we can't install Kolibri's However, the question is how much more time to spend on this. If there doesn't seem to be any efficient way forward, I think it'd be fine to just test what we can and then try it out in KDP as soon as it tracks the latest Kolibri, and contemplate how we can make this process feasible in the future. Would that be fine? |
upgrading kolibri into KDP involves several weeks of work due to the database and backend and frontend api changes. It's a task to be done and I'll do it after 0.16 is released, but it's not something that could be done in the scope of a test.
yep, the only alternative I can think is check if this change could be backported easily to kolibri 0.15, so no database or API's are affected. If that could be done easily we could test it. If not, your proposal is the only reasonable exit I see. |
I wasn't able to test this in KDP in a reasonable time frame I had for it, so if there are no other ideas, it can be tested as soon as KDP is up to date. |
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, @thanksameeelian. changes are looking good to me. I left some non-blocking comments and one question. Let's wait for the results of regression testing before merging.
@@ -552,6 +553,12 @@ | |||
break; | |||
} | |||
} | |||
|
|||
// look for KSelects nested within modals | |||
const allSelects = document.querySelectorAll('div.modal div.ui-select'); |
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'd recommend adding a comment to modal
element saying that it's being used by means of div.modal
selector in the KeenUiSelect
so that in the future, we prevent from this logic being silently broken in case someone removes or renames this class in KModal
(I think that quite commonly people won't get an idea to check if a class is used in another component before refactoring it)
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.
added explanatory comments to both KModal
& KeenUiSelect
above where class
is assigned within their templates - i'd love to hear what you think!
scrollShadow: false, | ||
delayedEnough: false, | ||
}; | ||
}, | ||
computed: { | ||
modalContentHeight() { | ||
return this.$refs.content.getBoundingClientRect().height || this.$refs.content.scrollHeight; |
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.
Just to understand, what situation was this ||
supposed to model?
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 the page initially loads, this.$refs.content.getBoundingClientRect().height
will very temporarily be 0
, so in that case we will use this.$refs.content.scrollHeight
, which will be accurate to the real contents of the modal (rather than the length of the dropdown) because the dropdown has not yet been opened.
i'll add in a code comment - please let me know if you think it's a sufficient explanation 🙂 this and several other of my additions were written to counteract all the strange cases i was able to encounter - without this specific check, upon initial load the modal is only rendered tall enough to contain its title, with its contents floating out in space over the grey overlay.
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.
Okay, thank you
@@ -241,6 +252,10 @@ | |||
}); | |||
window.addEventListener('focus', this.focusElementTest, true); | |||
window.setTimeout(() => (this.delayedEnough = true), 500); | |||
|
|||
// if modal contains KSelect, special classes & styles will be applied | |||
const kSelectCheck = document.querySelector('div.modal div.ui-select'); |
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'd recommend adding a comment to ui-select
element saying that it's being used by means of div.ui-select
selector in the KModal
(explained the reason for this in a similar comment for the KeenUiSelect
changes)
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.
added! (see related comment 🙂)
Regression testing approved, merging! |
Description
Previously, if
KSelect
was located within a modal, its height would be constrained to that of the modal and unnecessary scrollbars might appear. Addressed in this PR by conditionally applying styling toKModal
s &KSelect
s when they are used together, allowing modal overflow to remain visible in that special case. Note: currently across our codebase, this combination of components is only known to occur in KDP.Issue addressed
Addresses #324: Kmodal should be able to show dropdowns select without making scrollbars appear
Before/after screenshots
before (courtesy of #324)
after
(gif cuts off a little too soon after second dropdown selection - sorry!)
Steps to test
KModal
which contains aKSelect
KModal
&KeenUiSelect
calling for regression testingImplementation notes
many approaches to solving this problem were tried (see drafts of a couple attempted alternatives in #422 & #430), but were stymied by various issues as we tried to selectively or wholly update
KeenUiSelect
,KeenUiSelectOption
, andUiPopover
. after we initially vendored the file, KeenUI fundamentally changed the wayKeenUiSelect
interacts with the other two mentioned components (which were also refactored), making it difficult for us to successfully implement piecemeal code updates.the approach in this PR focuses on making minimal & conditional CSS changes to the code we currently have in place, in order to account for the challenges presented by the unique combination of
KModal
s &KSelect
s, which each have calculations & styling that weren't initially built to account for the properties of the other.the changes presented by this PR were built to account for three types of buggy behavior seen during development:
KSelect
- if exists, calculate height a special way so modal height does not stretch after dropdown is opened and closedKModal
component - allows dropdown menu to escape modal and extend as far as needed but shouldn’t effect any other usages of modalscalculateSpaceBelow()
inKeenUiSelect
when located inside a modal - because 1 & 2 are now working, it would check the modal for available space (even though the dropdown can extend beyond that space), and when it didn't find space available it would choose to render the dropdown above the input forKSelect
rather than below itTesting checklist
changelog
Reviewer guidance