@keenthemes/ktui 1.0.26 → 1.0.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ktui.js +136 -17
- package/dist/ktui.min.js +1 -1
- package/dist/ktui.min.js.map +1 -1
- package/dist/styles.css +6 -13
- package/examples/modal/remote-select-dropdown.html +166 -0
- package/examples/modal/select-dropdown-container.html +129 -0
- package/examples/select/modal-positioning-test.html +10 -8
- package/lib/cjs/components/modal/modal.js +13 -1
- package/lib/cjs/components/modal/modal.js.map +1 -1
- package/lib/cjs/components/select/dropdown.js +34 -6
- package/lib/cjs/components/select/dropdown.js.map +1 -1
- package/lib/cjs/components/select/select.js +89 -10
- package/lib/cjs/components/select/select.js.map +1 -1
- package/lib/esm/components/modal/modal.js +13 -1
- package/lib/esm/components/modal/modal.js.map +1 -1
- package/lib/esm/components/select/dropdown.js +34 -6
- package/lib/esm/components/select/dropdown.js.map +1 -1
- package/lib/esm/components/select/select.js +89 -10
- package/lib/esm/components/select/select.js.map +1 -1
- package/package.json +1 -1
- package/src/components/modal/modal.ts +15 -1
- package/src/components/select/dropdown.ts +42 -6
- package/src/components/select/select.ts +123 -10
- package/lib/cjs/components/config.js +0 -26
- package/lib/cjs/components/config.js.map +0 -1
- package/lib/cjs/components/config.umd.js +0 -23
- package/lib/cjs/components/config.umd.js.map +0 -1
- package/lib/cjs/components/menu/index.js +0 -6
- package/lib/cjs/components/menu/index.js.map +0 -1
- package/lib/cjs/components/menu/menu.js +0 -1021
- package/lib/cjs/components/menu/menu.js.map +0 -1
- package/lib/cjs/components/menu/types.js +0 -3
- package/lib/cjs/components/menu/types.js.map +0 -1
- package/lib/cjs/components/theme/index.js +0 -6
- package/lib/cjs/components/theme/index.js.map +0 -1
- package/lib/cjs/components/theme/theme.js +0 -147
- package/lib/cjs/components/theme/theme.js.map +0 -1
- package/lib/cjs/components/theme/types.js +0 -3
- package/lib/cjs/components/theme/types.js.map +0 -1
- package/lib/esm/components/config.js +0 -24
- package/lib/esm/components/config.js.map +0 -1
- package/lib/esm/components/config.umd.js +0 -23
- package/lib/esm/components/config.umd.js.map +0 -1
- package/lib/esm/components/menu/index.js +0 -2
- package/lib/esm/components/menu/index.js.map +0 -1
- package/lib/esm/components/menu/menu.js +0 -1018
- package/lib/esm/components/menu/menu.js.map +0 -1
- package/lib/esm/components/menu/types.js +0 -2
- package/lib/esm/components/menu/types.js.map +0 -1
- package/lib/esm/components/theme/index.js +0 -2
- package/lib/esm/components/theme/index.js.map +0 -1
- package/lib/esm/components/theme/theme.js +0 -144
- package/lib/esm/components/theme/theme.js.map +0 -1
- package/lib/esm/components/theme/types.js +0 -2
- package/lib/esm/components/theme/types.js.map +0 -1
- /package/examples/modal/{persistent-test.html → persistent.html} +0 -0
- /package/examples/select/{dark-mode-test.html → dark-mode.html} +0 -0
- /package/examples/select/{dropdowncontainer-test.html → dropdowncontainer.html} +0 -0
- /package/examples/select/{formdata-remote-test.html → formdata-remote.html} +0 -0
- /package/examples/select/{global-config-test.html → global-config.html} +0 -0
package/dist/ktui.js
CHANGED
|
@@ -9252,8 +9252,20 @@ var KTModal = /** @class */ (function (_super) {
|
|
|
9252
9252
|
KTModal.prototype._handlers = function () {
|
|
9253
9253
|
var _this = this;
|
|
9254
9254
|
this._element.addEventListener('click', function (event) {
|
|
9255
|
-
|
|
9255
|
+
var target = event.target;
|
|
9256
|
+
var currentTarget = event.currentTarget;
|
|
9257
|
+
// Only proceed if clicking directly on the backdrop (modal element itself)
|
|
9258
|
+
// This prevents closing when clicking inside modal content or any child elements
|
|
9259
|
+
// (including dropdowns rendered via dropdownContainer pointing to modal)
|
|
9260
|
+
if (target !== currentTarget) {
|
|
9261
|
+
// Stop propagation for clicks inside dropdowns to prevent dropdown from closing
|
|
9262
|
+
// Check if click is inside a dropdown element (KT Select dropdown)
|
|
9263
|
+
var dropdownElement = target.closest('[data-kt-select-dropdown]');
|
|
9264
|
+
if (dropdownElement) {
|
|
9265
|
+
event.stopPropagation();
|
|
9266
|
+
}
|
|
9256
9267
|
return;
|
|
9268
|
+
}
|
|
9257
9269
|
// Only hide if both backdropStatic is false AND persistent is false
|
|
9258
9270
|
if (_this._getOption('backdropStatic') === false &&
|
|
9259
9271
|
utils_1.default.stringToBoolean(_this._getOption('persistent')) === false) {
|
|
@@ -9576,8 +9588,14 @@ var KTSelectDropdown = /** @class */ (function (_super) {
|
|
|
9576
9588
|
_this._dropdownElement = dropdownElement;
|
|
9577
9589
|
_this._config = config;
|
|
9578
9590
|
_this._ktSelectInstance = ktSelectInstance; // Assign instance
|
|
9591
|
+
// For centered modals, don't move dropdown to container to preserve positioning context
|
|
9592
|
+
// For other cases, move to container if specified
|
|
9593
|
+
var modalParent = _this._getModalContainer();
|
|
9594
|
+
var isCenteredModal = modalParent && modalParent.classList.contains('kt-modal-center');
|
|
9595
|
+
// Only move dropdown if not in centered modal (regardless of strategy override)
|
|
9596
|
+
// This prevents the positioning bug even if user sets dropdownStrategy: 'fixed'
|
|
9579
9597
|
var container = _this._resolveDropdownContainer();
|
|
9580
|
-
if (container) {
|
|
9598
|
+
if (container && !isCenteredModal) {
|
|
9581
9599
|
if (container !== _this._dropdownElement.parentElement) {
|
|
9582
9600
|
container.appendChild(_this._dropdownElement);
|
|
9583
9601
|
}
|
|
@@ -9652,17 +9670,40 @@ var KTSelectDropdown = /** @class */ (function (_super) {
|
|
|
9652
9670
|
KTSelectDropdown.prototype._getModalContainer = function () {
|
|
9653
9671
|
return this._element.closest('[data-kt-modal], .kt-modal, .kt-modal-center');
|
|
9654
9672
|
};
|
|
9673
|
+
/**
|
|
9674
|
+
* Get the appropriate boundary element for Popper positioning
|
|
9675
|
+
* For centered modals, use .kt-modal-content to avoid transform calculation issues
|
|
9676
|
+
* @returns The boundary element, or null if no modal found
|
|
9677
|
+
*/
|
|
9678
|
+
KTSelectDropdown.prototype._getModalBoundary = function () {
|
|
9679
|
+
var modalParent = this._getModalContainer();
|
|
9680
|
+
if (!modalParent) {
|
|
9681
|
+
return null;
|
|
9682
|
+
}
|
|
9683
|
+
// For centered modals, use .kt-modal-content as boundary to avoid transform issues
|
|
9684
|
+
if (modalParent.classList.contains('kt-modal-center')) {
|
|
9685
|
+
var modalContent = modalParent.querySelector('.kt-modal-content');
|
|
9686
|
+
return modalContent || modalParent;
|
|
9687
|
+
}
|
|
9688
|
+
// For non-centered modals, use the modal element itself
|
|
9689
|
+
return modalParent;
|
|
9690
|
+
};
|
|
9655
9691
|
/**
|
|
9656
9692
|
* Get the appropriate positioning strategy based on context
|
|
9657
|
-
* @returns 'fixed' if inside modal, 'absolute'
|
|
9693
|
+
* @returns 'fixed' if inside non-centered modal, 'absolute' for centered modals or no modal
|
|
9658
9694
|
*/
|
|
9659
9695
|
KTSelectDropdown.prototype._getPositioningStrategy = function () {
|
|
9660
9696
|
// Check if config explicitly sets strategy
|
|
9661
9697
|
if (this._config.dropdownStrategy) {
|
|
9662
9698
|
return this._config.dropdownStrategy;
|
|
9663
9699
|
}
|
|
9664
|
-
//
|
|
9700
|
+
// For centered modals, use absolute positioning to avoid transform calculation issues
|
|
9701
|
+
// For non-centered modals, use fixed positioning
|
|
9665
9702
|
var modalParent = this._getModalContainer();
|
|
9703
|
+
if (modalParent && modalParent.classList.contains('kt-modal-center')) {
|
|
9704
|
+
return 'absolute';
|
|
9705
|
+
}
|
|
9706
|
+
// Use fixed positioning for non-centered modals
|
|
9666
9707
|
return modalParent ? 'fixed' : 'absolute';
|
|
9667
9708
|
};
|
|
9668
9709
|
/**
|
|
@@ -9678,9 +9719,8 @@ var KTSelectDropdown = /** @class */ (function (_super) {
|
|
|
9678
9719
|
var strategy = this._getPositioningStrategy();
|
|
9679
9720
|
var preventOverflow = this._config.dropdownPreventOverflow !== false;
|
|
9680
9721
|
var flip = this._config.dropdownFlip !== false;
|
|
9681
|
-
//
|
|
9682
|
-
var
|
|
9683
|
-
var boundary = modalParent || 'clippingParents';
|
|
9722
|
+
// Get appropriate boundary element for modal context
|
|
9723
|
+
var boundary = this._getModalBoundary() || 'clippingParents';
|
|
9684
9724
|
// Create new popper instance
|
|
9685
9725
|
this._popperInstance = (0, core_1.createPopper)(this._toggleElement, this._dropdownElement, {
|
|
9686
9726
|
placement: placement,
|
|
@@ -11894,6 +11934,12 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
11894
11934
|
KTSelect.prototype._completeRemoteSetup = function () {
|
|
11895
11935
|
// Initialize options
|
|
11896
11936
|
this._preSelectOptions(this._element);
|
|
11937
|
+
// Prevent browser auto-selection when placeholder is configured
|
|
11938
|
+
if (this._config.placeholder &&
|
|
11939
|
+
this._state.getSelectedOptions().length === 0 &&
|
|
11940
|
+
this._preSelectedValues.length === 0) {
|
|
11941
|
+
this._element.value = '';
|
|
11942
|
+
}
|
|
11897
11943
|
// Apply pre-selected values captured before remote data was loaded
|
|
11898
11944
|
if (this._preSelectedValues.length > 0) {
|
|
11899
11945
|
if (this._config.debug) {
|
|
@@ -12136,6 +12182,11 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12136
12182
|
this._setupElementReferences();
|
|
12137
12183
|
// Initialize options
|
|
12138
12184
|
this._preSelectOptions(this._element);
|
|
12185
|
+
// Prevent browser auto-selection when placeholder is configured
|
|
12186
|
+
if (this._config.placeholder &&
|
|
12187
|
+
this._state.getSelectedOptions().length === 0) {
|
|
12188
|
+
this._element.value = '';
|
|
12189
|
+
}
|
|
12139
12190
|
// Apply disabled state if needed
|
|
12140
12191
|
this._applyInitialDisabledState();
|
|
12141
12192
|
// Initialize search if enabled
|
|
@@ -13065,10 +13116,18 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
13065
13116
|
};
|
|
13066
13117
|
/**
|
|
13067
13118
|
* Update the dropdown to sync with native select element changes
|
|
13068
|
-
* For remote selects, refetches data from the server
|
|
13119
|
+
* For remote selects, refetches data from the server and preserves selections
|
|
13069
13120
|
* Optionally accepts new options to replace existing ones (static selects only)
|
|
13070
|
-
*
|
|
13121
|
+
*
|
|
13122
|
+
* @param newOptions Optional array of new options [{value, text}, ...] (static selects only)
|
|
13071
13123
|
* @public
|
|
13124
|
+
* @remarks
|
|
13125
|
+
* - For static selects: rebuilds dropdown from native select or new options
|
|
13126
|
+
* - For remote selects: fetches fresh data, preserves matching selections
|
|
13127
|
+
* - Selections are preserved if their values exist in new remote data
|
|
13128
|
+
* - Selections are cleared if their values don't exist in new data
|
|
13129
|
+
* @fires updated - After update completes successfully
|
|
13130
|
+
* @fires updateError - If remote data fetch fails
|
|
13072
13131
|
*/
|
|
13073
13132
|
KTSelect.prototype.update = function (newOptions) {
|
|
13074
13133
|
var _this = this;
|
|
@@ -13077,19 +13136,36 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
13077
13136
|
this._remoteModule
|
|
13078
13137
|
.fetchData()
|
|
13079
13138
|
.then(function (items) {
|
|
13080
|
-
//
|
|
13139
|
+
// Capture currently selected values before clearing
|
|
13140
|
+
var currentlySelected = _this._state.getSelectedOptions();
|
|
13141
|
+
// Clear existing options (also captures to _preSelectedValues)
|
|
13081
13142
|
_this._clearExistingOptions();
|
|
13082
|
-
//
|
|
13143
|
+
// Get all available values from new remote data
|
|
13144
|
+
var availableValues = items.map(function (item) { return item.id; });
|
|
13145
|
+
// Filter to only values that exist in new data
|
|
13146
|
+
var validSelections = currentlySelected.filter(function (value) {
|
|
13147
|
+
return availableValues.includes(value);
|
|
13148
|
+
});
|
|
13149
|
+
if (_this._config.debug && currentlySelected.length > 0) {
|
|
13150
|
+
console.log('update(): Preserving selections that exist in new data:', validSelections);
|
|
13151
|
+
}
|
|
13152
|
+
// Add new options from remote data and restore selection state
|
|
13083
13153
|
items.forEach(function (item) {
|
|
13084
13154
|
var option = document.createElement('option');
|
|
13085
13155
|
option.value = item.id;
|
|
13086
13156
|
option.textContent = item.title;
|
|
13087
13157
|
if (item.disabled)
|
|
13088
13158
|
option.disabled = true;
|
|
13159
|
+
// Restore selected attribute for preserved selections
|
|
13160
|
+
if (validSelections.includes(item.id)) {
|
|
13161
|
+
option.selected = true;
|
|
13162
|
+
}
|
|
13089
13163
|
_this._element.appendChild(option);
|
|
13090
13164
|
});
|
|
13091
13165
|
// Rebuild dropdown
|
|
13092
13166
|
_this._rebuildOptionsFromNative();
|
|
13167
|
+
// Sync selection state from native select (now has selected attributes)
|
|
13168
|
+
_this._syncSelectionFromNative();
|
|
13093
13169
|
// Dispatch updated event
|
|
13094
13170
|
_this._dispatchEvent('updated');
|
|
13095
13171
|
_this._fireEvent('updated');
|
|
@@ -13136,19 +13212,38 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
13136
13212
|
// Dispatch reload start event
|
|
13137
13213
|
this._dispatchEvent('reloadStart');
|
|
13138
13214
|
this._fireEvent('reloadStart');
|
|
13215
|
+
// Capture currently selected values before clearing
|
|
13216
|
+
var currentlySelected = this._state.getSelectedOptions();
|
|
13139
13217
|
// Fetch fresh remote data
|
|
13140
13218
|
return this._remoteModule
|
|
13141
13219
|
.fetchData()
|
|
13142
13220
|
.then(function (items) {
|
|
13143
|
-
// Clear existing options
|
|
13221
|
+
// Clear existing options (captures to _preSelectedValues)
|
|
13144
13222
|
_this._clearExistingOptions();
|
|
13145
13223
|
// Update state with new items
|
|
13146
13224
|
return _this._state.setItems(items).then(function () {
|
|
13147
13225
|
// Generate new options HTML
|
|
13148
13226
|
_this._generateOptionsHtml(_this._element);
|
|
13227
|
+
// Preserve selections by marking matching options as selected
|
|
13228
|
+
var availableValues = items.map(function (item) {
|
|
13229
|
+
return item.id !== undefined ? String(item.id) : '';
|
|
13230
|
+
});
|
|
13231
|
+
var validSelections = currentlySelected.filter(function (value) {
|
|
13232
|
+
return availableValues.includes(value);
|
|
13233
|
+
});
|
|
13234
|
+
if (_this._config.debug && currentlySelected.length > 0) {
|
|
13235
|
+
console.log('reload(): Preserving selections that exist in new data:', validSelections);
|
|
13236
|
+
}
|
|
13237
|
+
// Mark preserved selections on new options
|
|
13238
|
+
validSelections.forEach(function (value) {
|
|
13239
|
+
var option = Array.from(_this._element.querySelectorAll('option')).find(function (opt) { return opt.value === value; });
|
|
13240
|
+
if (option) {
|
|
13241
|
+
option.selected = true;
|
|
13242
|
+
}
|
|
13243
|
+
});
|
|
13149
13244
|
// Update the dropdown
|
|
13150
13245
|
_this._updateDropdownWithNewOptions();
|
|
13151
|
-
// Sync selection state from native select
|
|
13246
|
+
// Sync selection state from native select (now has selected attributes)
|
|
13152
13247
|
_this._syncSelectionFromNative();
|
|
13153
13248
|
// Update visual display
|
|
13154
13249
|
_this.updateSelectedOptionDisplay();
|
|
@@ -13173,8 +13268,17 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
13173
13268
|
};
|
|
13174
13269
|
/**
|
|
13175
13270
|
* Refresh the visual display and state without rebuilding options
|
|
13176
|
-
* For remote selects, refetches data from the server
|
|
13271
|
+
* For remote selects, refetches data from the server and preserves selections
|
|
13272
|
+
* that exist in the newly fetched data
|
|
13273
|
+
*
|
|
13177
13274
|
* @public
|
|
13275
|
+
* @remarks
|
|
13276
|
+
* - For static selects: syncs visual state with native select
|
|
13277
|
+
* - For remote selects: fetches fresh data, preserves matching selections
|
|
13278
|
+
* - Selections are preserved if their values exist in new remote data
|
|
13279
|
+
* - Selections are cleared if their values don't exist in new data
|
|
13280
|
+
* @fires refreshed - After refresh completes successfully
|
|
13281
|
+
* @fires refreshError - If remote data fetch fails
|
|
13178
13282
|
*/
|
|
13179
13283
|
KTSelect.prototype.refresh = function () {
|
|
13180
13284
|
var _this = this;
|
|
@@ -13183,20 +13287,35 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
13183
13287
|
this._remoteModule
|
|
13184
13288
|
.fetchData()
|
|
13185
13289
|
.then(function (items) {
|
|
13186
|
-
//
|
|
13290
|
+
// Capture currently selected values before clearing
|
|
13291
|
+
var currentlySelected = _this._state.getSelectedOptions();
|
|
13292
|
+
// Clear existing options (also captures to _preSelectedValues)
|
|
13187
13293
|
_this._clearExistingOptions();
|
|
13188
|
-
//
|
|
13294
|
+
// Get all available values from new remote data
|
|
13295
|
+
var availableValues = items.map(function (item) { return item.id; });
|
|
13296
|
+
// Filter to only values that exist in new data
|
|
13297
|
+
var validSelections = currentlySelected.filter(function (value) {
|
|
13298
|
+
return availableValues.includes(value);
|
|
13299
|
+
});
|
|
13300
|
+
if (_this._config.debug && currentlySelected.length > 0) {
|
|
13301
|
+
console.log('refresh(): Preserving selections that exist in new data:', validSelections);
|
|
13302
|
+
}
|
|
13303
|
+
// Add new options and restore selection state
|
|
13189
13304
|
items.forEach(function (item) {
|
|
13190
13305
|
var option = document.createElement('option');
|
|
13191
13306
|
option.value = item.id;
|
|
13192
13307
|
option.textContent = item.title;
|
|
13193
13308
|
if (item.disabled)
|
|
13194
13309
|
option.disabled = true;
|
|
13310
|
+
// Restore selected attribute for preserved selections
|
|
13311
|
+
if (validSelections.includes(item.id)) {
|
|
13312
|
+
option.selected = true;
|
|
13313
|
+
}
|
|
13195
13314
|
_this._element.appendChild(option);
|
|
13196
13315
|
});
|
|
13197
13316
|
// Rebuild dropdown
|
|
13198
13317
|
_this._rebuildOptionsFromNative();
|
|
13199
|
-
// Sync selection state
|
|
13318
|
+
// Sync selection state from native select (now has selected attributes)
|
|
13200
13319
|
_this._syncSelectionFromNative();
|
|
13201
13320
|
// Reapply ARIA attributes
|
|
13202
13321
|
_this._setAriaAttributes();
|