diff --git a/docs/pages/kselectinkmodal.vue b/docs/pages/kselectinkmodal.vue
new file mode 100644
index 000000000..4174300fb
--- /dev/null
+++ b/docs/pages/kselectinkmodal.vue
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+ Value: {{ exampleData }}
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/tableOfContents.js b/docs/tableOfContents.js
index 6a2419979..5cd13791c 100644
--- a/docs/tableOfContents.js
+++ b/docs/tableOfContents.js
@@ -254,6 +254,11 @@ export default [
isCode: true,
keywords: ['field', 'box'],
}),
+ new Page({
+ path: '/kselectinkmodal',
+ title: 'KSelectInKModal',
+ isCode: true,
+ }),
new Page({
path: '/kswitch',
title: 'KSwitch',
diff --git a/lib/KSelect/KeenUiSelect.vue b/lib/KSelect/KeenUiSelect.vue
index b966eec45..6b7a93593 100644
--- a/lib/KSelect/KeenUiSelect.vue
+++ b/lib/KSelect/KeenUiSelect.vue
@@ -32,7 +32,6 @@
:class="$computedClass({ ':focus': $coreOutline })"
:tabindex="disabled ? null : '0'"
- @click="toggleDropdown"
@focus="onFocus"
@keydown.enter.prevent="openDropdown"
@keydown.space.prevent="openDropdown"
@@ -75,11 +74,18 @@
/>
-
+
-
+
@@ -194,6 +200,7 @@
import startswith from 'lodash/startsWith';
import sortby from 'lodash/sortBy';
import UiIcon from '../keen/UiIcon';
+ import UiPopover from '../keen/UiPopover';
import { looseIndexOf, looseEqual } from '../keen/helpers/util';
import { scrollIntoView, resetScroll } from '../keen/helpers/element-scroll';
@@ -204,6 +211,7 @@
name: 'KeenUiSelect',
components: {
UiIcon,
+ UiPopover,
KeenUiSelectOption,
},
props: {
@@ -319,7 +327,6 @@
isActive: false,
isTouched: false,
highlightedOption: null,
- showDropdown: false,
initialValue: JSON.stringify(this.value),
quickMatchString: '',
quickMatchTimeout: null,
@@ -463,7 +470,6 @@
option[this.keys.label].toLowerCase(),
this.quickMatchString.toLowerCase()
);
-
return option;
});
},
@@ -500,16 +506,6 @@
resetScroll(this.$refs.optionsList);
},
- showDropdown() {
- if (this.showDropdown) {
- this.onOpen();
- this.$emit('dropdown-open');
- } else {
- this.onClose();
- this.$emit('dropdown-close');
- }
- },
-
query() {
this.$emit('query-change', this.query);
},
@@ -534,7 +530,7 @@
},
mounted() {
- document.addEventListener('click', this.onExternalClick);
+ this.addExternalClickListener(this.$el, this.onExternalClick);
// Find nearest scrollable ancestor
this.scrollableAncestor = this.$el;
while (
@@ -555,10 +551,29 @@
},
beforeDestroy() {
- document.removeEventListener('click', this.onExternalClick);
+ this.removeExternalClickListener();
},
methods: {
+ addExternalClickListener(element = this.$el, callback = null) {
+ this.externalClickListener = e => {
+ if (!element.contains(e.target)) {
+ if (typeof callback === 'function') {
+ callback(e);
+ } else {
+ this.$emit('external-click', e);
+ }
+ }
+ };
+
+ document.addEventListener('click', this.externalClickListener);
+ },
+
+ removeExternalClickListener() {
+ document.removeEventListener('click', this.externalClickListener);
+ this.externalClickListener = null;
+ },
+
setValue(value) {
value = value ? value : this.multiple ? [] : '';
@@ -743,11 +758,6 @@
this.query = '';
},
- toggleDropdown() {
- this.calculateSpaceBelow();
- this[this.showDropdown ? 'closeDropdown' : 'openDropdown']();
- },
-
openDropdown() {
if (this.disabled || this.clearableState) {
return;
@@ -757,7 +767,7 @@
this.highlightNextOption();
}
- this.showDropdown = true;
+ this.$refs.dropdown.open();
// IE: clicking label doesn't focus the select element
// to set isActive to true
if (!this.isActive) {
@@ -766,7 +776,7 @@
},
closeDropdown(options = { autoBlur: false }) {
- this.showDropdown = false;
+ this.$refs.dropdown.close();
this.query = '';
if (!this.isTouched) {
this.isTouched = true;
@@ -780,8 +790,35 @@
}
},
+ // !!!!!!!!!!!!!!! functionality lost due to refactoring when updating this file to align with
+ // changes KeenUI's made to their source code to fix "dropdown getting stuck inside modal" problem -- KeenUi also
+ // refactored their UiPopover, adding in a new JS dropdown library and a couple related dependencies. i wanted to
+ // avoid expanding the scope of this PR and its testing so did not make the same changes to our vendored UiPopover,
+ // concerned about unintended effects on our other components that use our current version of UiPopover.
+
+ // i have attempted to take what we need from KeenUI's update to UiSelect and accomplish the rest through
+ // additional functions & CSS targeting. the dropdown now extends beyond the modal as desired but you cannot tab
+ // through it and it does not highlight upon mouseover (though that specifically could be solved with CSS :hover
+ // targeting, it doesn't address the underlying loss of functionality)
+ //
+ // each time i end up in a tangle...some highlights (lowlights haha):
+
+ // - with unintended side effects leading to behavior of dropdown closing upon highlight;
+
+ // - unsuccessfully attempted to adapt functionality from KDropdownMenu where UiPopover is ostensibly working with
+ // highlight functions [rather than CSS targeting of :hover] & tabbing through options;
+ //
+ // - this onMouseover function is "working" and mouseovers are registering, still not providing desired
+ // highlight-upon-hover functionality;
+ //
+ // - CSS targeting of each element on :hover in KeenUiSelectOption solves highlight-upon-hover issue on surface
+ // level but does not address inability to tab through options and simply disguises broken functionality underneath).
+ //
+
+ // have tried to clean up most attempts since they were muddying the waters ðŸ«
+
onMouseover(option) {
- if (this.showDropdown) {
+ if (this.$refs.dropdown.isOpen()) {
this.highlightOption(option, { autoScroll: false });
}
},
@@ -799,15 +836,20 @@
this.isActive = false;
this.$emit('blur', e);
- if (this.showDropdown) {
+ if (this.$refs.dropdown.isOpen()) {
this.closeDropdown({ autoBlur: true });
}
},
onOpen() {
+ document.addEventListener('scroll', this.onExternalScroll, true);
+ this.$emit('dropdown-open');
+
+ this.$refs.dropdown.$el.style.width = this.$refs.label.getBoundingClientRect().width + 'px';
+
this.highlightedOption = this.multiple ? null : this.value;
this.$nextTick(() => {
- this.$refs[this.hasSearch ? 'searchInput' : 'dropdown'].focus();
+ this.$refs[this.hasSearch ? 'searchInput' : 'dropdownContent'].focus();
const selectedOption = this.$refs.optionsList.querySelector('.is-selected');
if (selectedOption) {
this.scrollOptionIntoView(selectedOption);
@@ -820,16 +862,24 @@
},
onClose() {
+ document.removeEventListener('scroll', this.onExternalScroll, true);
+
this.highlightedOption = this.multiple ? null : this.value;
+
+ this.$emit('dropdown-close');
},
- onExternalClick(e) {
- if (!this.$el.contains(e.target)) {
- if (this.showDropdown) {
- this.closeDropdown({ autoBlur: true });
- } else if (this.isActive) {
- this.isActive = false;
- }
+ onExternalClick() {
+ if (this.$refs.dropdown.isOpen()) {
+ this.closeDropdown({ autoBlur: true });
+ } else if (this.isActive) {
+ this.isActive = false;
+ }
+ },
+
+ onExternalScroll(e) {
+ if (e.target !== this.$refs.optionsList) {
+ this.closeDropdown();
}
},
@@ -853,6 +903,7 @@
resetTouched(options = { touched: false }) {
this.isTouched = options.touched;
},
+
calculateSpaceBelow() {
// Get the height of element
const buttonHeight = this.$el.getBoundingClientRect().height;
@@ -998,7 +1049,6 @@
}
.ui-select-label {
- position: relative;
display: block;
width: 100%;
padding: 0;
@@ -1072,7 +1122,6 @@
.ui-select-dropdown {
position: absolute;
- z-index: $z-index-dropdown;
display: block;
width: 100%;
min-width: rem-calc(180px);
@@ -1081,7 +1130,10 @@
margin-bottom: rem-calc(8px);
list-style-type: none;
outline: none;
- box-shadow: 1px 2px 8px $md-grey-600;
+ }
+
+ .ui-select-dropdown-content {
+ outline: none;
}
.ui-select-search-input {
@@ -1170,20 +1222,6 @@
}
}
- // ================================================
- // Transitions
- // ================================================
-
- .ui-select-transition-fade-enter-active,
- .ui-select-transition-fade-leave-active {
- transition: opacity 0.2s ease;
- }
-
- .ui-select-transition-fade-enter,
- .ui-select-transition-fade-leave-active {
- opacity: 0;
- }
-
/* stylelint-enable */
.overlay-close-button {
diff --git a/lib/KSelectInKModal.vue b/lib/KSelectInKModal.vue
new file mode 100644
index 000000000..aae83ede6
--- /dev/null
+++ b/lib/KSelectInKModal.vue
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+