Skip to content

Commit

Permalink
Merge pull request #429 from thanksameeelian/kselect-scrollbars-kmoda…
Browse files Browse the repository at this point in the history
…l-cohacking-fork

allow kselect to extend outside of kmodal
  • Loading branch information
rtibbles authored Apr 15, 2023
2 parents 388f870 + 75a66c8 commit c414c14
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 9 deletions.
45 changes: 37 additions & 8 deletions lib/KModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,18 @@
@keyup.esc.stop="emitCancelEvent"
@keyup.enter="handleEnter"
>
<!-- KeenUiSelect targets modal by using div.modal selector -->
<div
ref="modal"
class="modal"
:tabindex="0"
role="dialog"
aria-labelledby="modal-title"
:style="[ modalSizeStyles, { background: $themeTokens.surface } ]"
:style="[
modalSizeStyles,
{ background: $themeTokens.surface },
containsKSelect ? { overflowY: 'unset' } : { overflowY: 'auto' }
]"
>

<!-- Modal Title -->
Expand Down Expand Up @@ -48,7 +53,10 @@
borderTop: `1px solid ${$themeTokens.fineLine}`,
borderBottom: `1px solid ${$themeTokens.fineLine}`,
} : {} ]"
:class="{ 'scroll-shadow': scrollShadow }"
:class="{
'scroll-shadow': scrollShadow,
'contains-kselect': containsKSelect
}"
>
<!-- @slot Main content of modal -->
<slot></slot>
Expand Down Expand Up @@ -182,11 +190,19 @@
lastFocus: null,
maxContentHeight: '1000',
contentHeight: 0,
containsKSelect: false,
scrollShadow: false,
delayedEnough: false,
};
},
computed: {
modalContentHeight() {
// if modal contains KSelect, the correct value of its content.scrollHeight is overwritten by the height of the
// KSelect options once KSelect is opened & the modal will elongate after KSelect is closed.
// in that case, getBoundingClientRect().height is a better reflection of content height but during the loading
// state it is temporarily 0 and fallback content.scrollHeight is accurate, as KSelect has not yet been opened
return this.$refs.content.getBoundingClientRect().height || this.$refs.content.scrollHeight;
},
modalSizeStyles() {
return {
'max-width': `${this.maxModalWidth - 32}px`,
Expand Down Expand Up @@ -241,6 +257,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');
this.containsKSelect = !!kSelectCheck;
},
updated() {
this.updateContentSectionStyle();
Expand All @@ -265,24 +285,30 @@
updateContentSectionStyle: debounce(function() {
if (this.$refs.title && this.$refs.actions) {
if (Math.abs(this.$refs.content.scrollHeight - this.contentHeight) >= 8) {
this.contentHeight = this.$refs.content.scrollHeight;
// if there's dropdown & it is opened, the new scrollHeight detected shouldn't be applied,
// or else the modal will elongate after the dropdown content has been closed
this.contentHeight = this.containsKSelect
? this.modalContentHeight
: this.$refs.content.scrollHeight;
}
const maxContentHeightCheck =
this.windowHeight -
this.$refs.title.clientHeight -
this.$refs.actions.clientHeight -
32;
// to prevent max height from toggling between pixels
// we set a threshold of how many pixels the height should change before we update
if (Math.abs(maxContentHeightCheck - this.maxContentHeight) >= 8) {
this.maxContentHeight = maxContentHeightCheck;
this.scrollShadow = this.maxContentHeight < this.$refs.content.scrollHeight;
}
// make sure that overflow-y won't be updated to 'auto' if this
// function is running for the first time
// (otherwise Firefox would add a vertical scrollbar right away)
if (this.$refs.content.clientHeight !== 0) {
// make sure that overflow-y won't be updated to 'auto' if this function is running for the first time
// (otherwise Firefox would add a vertical scrollbar right away) + don't apply if modal contains KSelect
// (otherwise KSelect will be trapped inside modal if KSelect is opened a second time)
if (this.$refs.content.clientHeight !== 0 && !this.containsKSelect) {
// add a vertical scrollbar if content doesn't fit
if (this.$refs.content.scrollHeight > this.$refs.content.clientHeight) {
this.$refs.content.style.overflowY = 'auto';
Expand Down Expand Up @@ -365,7 +391,6 @@
top: 50%;
left: 50%;
margin: 0 auto;
overflow-y: auto;
border-radius: $radius;
transform: translate(-50%, -50%);
Expand Down Expand Up @@ -409,6 +434,10 @@
background-size: 100% 20px, 100% 20px, 100% 10px, 100% 10px;
}
.contains-kselect {
overflow: unset;
}
.actions {
padding: 24px;
text-align: right;
Expand Down
15 changes: 14 additions & 1 deletion lib/KSelect/KeenUiSelect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
The formatting has been changed to match our linters. We may eventually
want to simply consolidate it with our component and remove any unused
functionality.
BELOW: KModal targets KeenUiSelect by using div.ui-select selector
-->
<div class="ui-select" :class="classes">
<input
Expand Down Expand Up @@ -316,6 +318,7 @@
data() {
return {
query: '',
isInsideModal: false,
isActive: false,
isTouched: false,
highlightedOption: null,
Expand Down Expand Up @@ -552,6 +555,12 @@
break;
}
}
// look for KSelects nested within modals
const allSelects = document.querySelectorAll('div.modal div.ui-select');
// create array from a nodelist [IE does not support Array.from()]
const allSelectsArr = Array.prototype.slice.call(allSelects);
this.isInsideModal = allSelectsArr.includes(this.$el);
},
beforeDestroy() {
Expand Down Expand Up @@ -744,7 +753,11 @@
},
toggleDropdown() {
this.calculateSpaceBelow();
// if called on dropdown inside modal, dropdown will generally render above input/placeholder when opened,
// rather than below it: we want to render dropdown above input only in cases where there isn't enough
// space available beneath input, but when dropdown extends outside a modal the func doesn't work as intended
if (!this.isInsideModal) this.calculateSpaceBelow();
this[this.showDropdown ? 'closeDropdown' : 'openDropdown']();
},
Expand Down

0 comments on commit c414c14

Please sign in to comment.