@keenthemes/ktui 1.0.25 → 1.0.26
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 +213 -33
- package/dist/ktui.min.js +1 -1
- package/dist/ktui.min.js.map +1 -1
- package/dist/styles.css +210 -0
- package/examples/datatable/checkbox-events-test.html +400 -0
- package/examples/datatable/credentials-test.html +423 -0
- package/examples/datatable/remote-checkbox-test.html +365 -0
- package/examples/modal/persistent-test.html +205 -0
- package/examples/select/formdata-remote-test.html +161 -0
- package/examples/select/modal-positioning-test.html +336 -0
- package/lib/cjs/components/datatable/datatable-checkbox.js +16 -3
- package/lib/cjs/components/datatable/datatable-checkbox.js.map +1 -1
- package/lib/cjs/components/datatable/datatable.js +3 -5
- package/lib/cjs/components/datatable/datatable.js.map +1 -1
- package/lib/cjs/components/image-input/image-input.js.map +1 -1
- package/lib/cjs/components/modal/modal.js +3 -1
- package/lib/cjs/components/modal/modal.js.map +1 -1
- package/lib/cjs/components/select/config.js +5 -0
- package/lib/cjs/components/select/config.js.map +1 -1
- package/lib/cjs/components/select/dropdown.js +25 -2
- package/lib/cjs/components/select/dropdown.js.map +1 -1
- package/lib/cjs/components/select/select.js +161 -22
- package/lib/cjs/components/select/select.js.map +1 -1
- package/lib/cjs/components/select/templates.js.map +1 -1
- package/lib/esm/components/datatable/datatable-checkbox.js +16 -3
- package/lib/esm/components/datatable/datatable-checkbox.js.map +1 -1
- package/lib/esm/components/datatable/datatable.js +3 -5
- package/lib/esm/components/datatable/datatable.js.map +1 -1
- package/lib/esm/components/image-input/image-input.js.map +1 -1
- package/lib/esm/components/modal/modal.js +3 -1
- package/lib/esm/components/modal/modal.js.map +1 -1
- package/lib/esm/components/select/config.js +5 -0
- package/lib/esm/components/select/config.js.map +1 -1
- package/lib/esm/components/select/dropdown.js +25 -2
- package/lib/esm/components/select/dropdown.js.map +1 -1
- package/lib/esm/components/select/select.js +161 -22
- package/lib/esm/components/select/select.js.map +1 -1
- package/lib/esm/components/select/templates.js.map +1 -1
- package/package.json +1 -1
- package/src/components/datatable/datatable-checkbox.ts +18 -3
- package/src/components/datatable/datatable.ts +3 -0
- package/src/components/datatable/types.ts +1 -0
- package/src/components/image-input/image-input.ts +12 -15
- package/src/components/modal/modal.ts +5 -1
- package/src/components/select/config.ts +6 -0
- package/src/components/select/dropdown.ts +32 -3
- package/src/components/select/select.ts +192 -35
- package/src/components/select/templates.ts +2 -1
package/dist/ktui.js
CHANGED
|
@@ -6993,8 +6993,11 @@ function createCheckboxHandler(element, config, fireEvent) {
|
|
|
6993
6993
|
return;
|
|
6994
6994
|
var value = input.value;
|
|
6995
6995
|
var selectedRows = getSelectedRows();
|
|
6996
|
-
|
|
6997
|
-
|
|
6996
|
+
var wasChecked = selectedRows.includes(value);
|
|
6997
|
+
var isNowChecked = input.checked;
|
|
6998
|
+
// Update state first
|
|
6999
|
+
if (isNowChecked) {
|
|
7000
|
+
if (!wasChecked)
|
|
6998
7001
|
selectedRows.push(value);
|
|
6999
7002
|
}
|
|
7000
7003
|
else {
|
|
@@ -7002,14 +7005,24 @@ function createCheckboxHandler(element, config, fireEvent) {
|
|
|
7002
7005
|
}
|
|
7003
7006
|
setSelectedRows(selectedRows);
|
|
7004
7007
|
updateHeaderCheckboxState();
|
|
7008
|
+
// Fire specific checked/unchecked events after state is updated
|
|
7009
|
+
if (isNowChecked && !wasChecked) {
|
|
7010
|
+
fireEvent('checked');
|
|
7011
|
+
}
|
|
7012
|
+
else if (!isNowChecked && wasChecked) {
|
|
7013
|
+
fireEvent('unchecked');
|
|
7014
|
+
}
|
|
7015
|
+
// Always fire changed event for backward compatibility
|
|
7005
7016
|
fireEvent('changed');
|
|
7006
7017
|
}
|
|
7007
7018
|
// When the header checkbox is toggled
|
|
7008
7019
|
function checkboxToggle(event) {
|
|
7009
7020
|
var checked = !isChecked();
|
|
7021
|
+
// Update state first, then fire events
|
|
7022
|
+
change(checked);
|
|
7023
|
+
// Fire checked/unchecked events after state is updated
|
|
7010
7024
|
var eventType = checked ? 'checked' : 'unchecked';
|
|
7011
7025
|
fireEvent(eventType);
|
|
7012
|
-
change(checked);
|
|
7013
7026
|
}
|
|
7014
7027
|
// Change all visible checkboxes and update selectedRows
|
|
7015
7028
|
function change(checked) {
|
|
@@ -8405,11 +8418,9 @@ var KTDataTable = /** @class */ (function (_super) {
|
|
|
8405
8418
|
apiEndpointWithQueryParams.search = queryParams.toString();
|
|
8406
8419
|
this._config.apiEndpoint = apiEndpointWithQueryParams.toString();
|
|
8407
8420
|
}
|
|
8408
|
-
return [2 /*return*/, fetch(this._config.apiEndpoint, {
|
|
8409
|
-
|
|
8410
|
-
|
|
8411
|
-
headers: this._config.requestHeaders,
|
|
8412
|
-
}).catch(function (error) {
|
|
8421
|
+
return [2 /*return*/, fetch(this._config.apiEndpoint, __assign({ method: requestMethod, body: requestBody, headers: this._config.requestHeaders }, (this._config.requestCredentials && {
|
|
8422
|
+
credentials: this._config.requestCredentials,
|
|
8423
|
+
}))).catch(function (error) {
|
|
8413
8424
|
// Trigger an error event
|
|
8414
8425
|
_this._fireEvent('error', { error: error });
|
|
8415
8426
|
_this._dispatchEvent('error', { error: error });
|
|
@@ -9243,7 +9254,9 @@ var KTModal = /** @class */ (function (_super) {
|
|
|
9243
9254
|
this._element.addEventListener('click', function (event) {
|
|
9244
9255
|
if (_this._element !== event.target)
|
|
9245
9256
|
return;
|
|
9246
|
-
if
|
|
9257
|
+
// Only hide if both backdropStatic is false AND persistent is false
|
|
9258
|
+
if (_this._getOption('backdropStatic') === false &&
|
|
9259
|
+
utils_1.default.stringToBoolean(_this._getOption('persistent')) === false) {
|
|
9247
9260
|
_this._hide();
|
|
9248
9261
|
}
|
|
9249
9262
|
});
|
|
@@ -9632,6 +9645,26 @@ var KTSelectDropdown = /** @class */ (function (_super) {
|
|
|
9632
9645
|
this._dropdownElement.style.width = "".concat(toggleWidth, "px");
|
|
9633
9646
|
}
|
|
9634
9647
|
};
|
|
9648
|
+
/**
|
|
9649
|
+
* Detect if the select is inside a modal container
|
|
9650
|
+
* @returns The modal element if found, null otherwise
|
|
9651
|
+
*/
|
|
9652
|
+
KTSelectDropdown.prototype._getModalContainer = function () {
|
|
9653
|
+
return this._element.closest('[data-kt-modal], .kt-modal, .kt-modal-center');
|
|
9654
|
+
};
|
|
9655
|
+
/**
|
|
9656
|
+
* Get the appropriate positioning strategy based on context
|
|
9657
|
+
* @returns 'fixed' if inside modal, 'absolute' otherwise
|
|
9658
|
+
*/
|
|
9659
|
+
KTSelectDropdown.prototype._getPositioningStrategy = function () {
|
|
9660
|
+
// Check if config explicitly sets strategy
|
|
9661
|
+
if (this._config.dropdownStrategy) {
|
|
9662
|
+
return this._config.dropdownStrategy;
|
|
9663
|
+
}
|
|
9664
|
+
// Use fixed positioning if inside a modal (to handle transform-based centering)
|
|
9665
|
+
var modalParent = this._getModalContainer();
|
|
9666
|
+
return modalParent ? 'fixed' : 'absolute';
|
|
9667
|
+
};
|
|
9635
9668
|
/**
|
|
9636
9669
|
* Initialize the Popper instance for dropdown positioning
|
|
9637
9670
|
*/
|
|
@@ -9642,9 +9675,12 @@ var KTSelectDropdown = /** @class */ (function (_super) {
|
|
|
9642
9675
|
var offsetValue = '0, 5';
|
|
9643
9676
|
// Get configuration options
|
|
9644
9677
|
var placement = this._config.dropdownPlacement || 'bottom-start';
|
|
9645
|
-
var strategy = this.
|
|
9678
|
+
var strategy = this._getPositioningStrategy();
|
|
9646
9679
|
var preventOverflow = this._config.dropdownPreventOverflow !== false;
|
|
9647
9680
|
var flip = this._config.dropdownFlip !== false;
|
|
9681
|
+
// Detect modal container for boundary
|
|
9682
|
+
var modalParent = this._getModalContainer();
|
|
9683
|
+
var boundary = modalParent || 'clippingParents';
|
|
9648
9684
|
// Create new popper instance
|
|
9649
9685
|
this._popperInstance = (0, core_1.createPopper)(this._toggleElement, this._dropdownElement, {
|
|
9650
9686
|
placement: placement,
|
|
@@ -9659,7 +9695,7 @@ var KTSelectDropdown = /** @class */ (function (_super) {
|
|
|
9659
9695
|
{
|
|
9660
9696
|
name: 'preventOverflow',
|
|
9661
9697
|
options: {
|
|
9662
|
-
boundary:
|
|
9698
|
+
boundary: boundary,
|
|
9663
9699
|
altAxis: preventOverflow,
|
|
9664
9700
|
},
|
|
9665
9701
|
},
|
|
@@ -12533,6 +12569,22 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12533
12569
|
selectedOptions: this.getSelectedOptions(),
|
|
12534
12570
|
});
|
|
12535
12571
|
};
|
|
12572
|
+
/**
|
|
12573
|
+
* Sync native select value attribute for FormData support
|
|
12574
|
+
*/
|
|
12575
|
+
KTSelect.prototype._syncNativeSelectValue = function () {
|
|
12576
|
+
var selectedOptions = this.getSelectedOptions();
|
|
12577
|
+
if (this._config.multiple) {
|
|
12578
|
+
// For multiple select, the selected options are marked via option.selected
|
|
12579
|
+
// The native select's value property will return the first selected option's value
|
|
12580
|
+
// FormData will include all selected values automatically
|
|
12581
|
+
}
|
|
12582
|
+
else {
|
|
12583
|
+
// For single select, set the value attribute explicitly
|
|
12584
|
+
var selectedValue = selectedOptions.length > 0 ? selectedOptions[0] : '';
|
|
12585
|
+
this._element.value = selectedValue;
|
|
12586
|
+
}
|
|
12587
|
+
};
|
|
12536
12588
|
/**
|
|
12537
12589
|
* Update selected option display value
|
|
12538
12590
|
*/
|
|
@@ -12540,6 +12592,8 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12540
12592
|
var selectedOptions = this.getSelectedOptions();
|
|
12541
12593
|
var tagsEnabled = this._config.tags && this._tagsModule;
|
|
12542
12594
|
var valueDisplayEl = this.getValueDisplayElement();
|
|
12595
|
+
// Sync native select value for FormData support
|
|
12596
|
+
this._syncNativeSelectValue();
|
|
12543
12597
|
if (tagsEnabled) {
|
|
12544
12598
|
// Tags module will render tags if selectedOptions > 0, or clear them if selectedOptions === 0.
|
|
12545
12599
|
this._tagsModule.updateTagsDisplay(selectedOptions);
|
|
@@ -12641,6 +12695,8 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12641
12695
|
Array.from(this._element.querySelectorAll('option')).forEach(function (opt) {
|
|
12642
12696
|
opt.selected = false;
|
|
12643
12697
|
});
|
|
12698
|
+
// Clear native select value
|
|
12699
|
+
this._element.value = '';
|
|
12644
12700
|
this.updateSelectedOptionDisplay();
|
|
12645
12701
|
this._updateSelectedOptionClass();
|
|
12646
12702
|
// Update select all button state
|
|
@@ -13009,41 +13065,160 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
13009
13065
|
};
|
|
13010
13066
|
/**
|
|
13011
13067
|
* Update the dropdown to sync with native select element changes
|
|
13012
|
-
*
|
|
13068
|
+
* For remote selects, refetches data from the server
|
|
13069
|
+
* Optionally accepts new options to replace existing ones (static selects only)
|
|
13013
13070
|
* @param newOptions Optional array of new options [{value, text}, ...]
|
|
13014
13071
|
* @public
|
|
13015
13072
|
*/
|
|
13016
13073
|
KTSelect.prototype.update = function (newOptions) {
|
|
13017
13074
|
var _this = this;
|
|
13018
|
-
|
|
13019
|
-
|
|
13020
|
-
this.
|
|
13021
|
-
|
|
13022
|
-
|
|
13023
|
-
|
|
13024
|
-
|
|
13025
|
-
|
|
13026
|
-
|
|
13075
|
+
// For remote selects, refetch data
|
|
13076
|
+
if (this._config.remote && this._remoteModule) {
|
|
13077
|
+
this._remoteModule
|
|
13078
|
+
.fetchData()
|
|
13079
|
+
.then(function (items) {
|
|
13080
|
+
// Clear existing options
|
|
13081
|
+
_this._clearExistingOptions();
|
|
13082
|
+
// Add new options from remote data
|
|
13083
|
+
items.forEach(function (item) {
|
|
13084
|
+
var option = document.createElement('option');
|
|
13085
|
+
option.value = item.id;
|
|
13086
|
+
option.textContent = item.title;
|
|
13087
|
+
if (item.disabled)
|
|
13088
|
+
option.disabled = true;
|
|
13089
|
+
_this._element.appendChild(option);
|
|
13090
|
+
});
|
|
13091
|
+
// Rebuild dropdown
|
|
13092
|
+
_this._rebuildOptionsFromNative();
|
|
13093
|
+
// Dispatch updated event
|
|
13094
|
+
_this._dispatchEvent('updated');
|
|
13095
|
+
_this._fireEvent('updated');
|
|
13096
|
+
})
|
|
13097
|
+
.catch(function (error) {
|
|
13098
|
+
console.error('Error updating remote data:', error);
|
|
13099
|
+
_this._dispatchEvent('updateError');
|
|
13100
|
+
_this._fireEvent('updateError');
|
|
13027
13101
|
});
|
|
13028
13102
|
}
|
|
13029
|
-
|
|
13030
|
-
|
|
13031
|
-
|
|
13032
|
-
|
|
13033
|
-
|
|
13103
|
+
else {
|
|
13104
|
+
// For static selects, handle new options
|
|
13105
|
+
if (newOptions) {
|
|
13106
|
+
// Clear existing options except placeholder
|
|
13107
|
+
this._clearExistingOptions();
|
|
13108
|
+
// Add new options to native select
|
|
13109
|
+
newOptions.forEach(function (opt) {
|
|
13110
|
+
var option = document.createElement('option');
|
|
13111
|
+
option.value = opt.value;
|
|
13112
|
+
option.textContent = opt.text;
|
|
13113
|
+
_this._element.appendChild(option);
|
|
13114
|
+
});
|
|
13115
|
+
}
|
|
13116
|
+
// Rebuild dropdown from native select
|
|
13117
|
+
this._rebuildOptionsFromNative();
|
|
13118
|
+
// Dispatch updated event
|
|
13119
|
+
this._dispatchEvent('updated');
|
|
13120
|
+
this._fireEvent('updated');
|
|
13121
|
+
}
|
|
13122
|
+
};
|
|
13123
|
+
/**
|
|
13124
|
+
* Reload remote data and rebuild the dropdown
|
|
13125
|
+
* Only works with remote data enabled
|
|
13126
|
+
* @returns Promise that resolves when reload completes
|
|
13127
|
+
* @public
|
|
13128
|
+
*/
|
|
13129
|
+
KTSelect.prototype.reload = function () {
|
|
13130
|
+
var _this = this;
|
|
13131
|
+
// Guard clause: only works with remote data
|
|
13132
|
+
if (!this._config.remote || !this._remoteModule) {
|
|
13133
|
+
console.warn('reload() only works with remote data enabled');
|
|
13134
|
+
return Promise.resolve();
|
|
13135
|
+
}
|
|
13136
|
+
// Dispatch reload start event
|
|
13137
|
+
this._dispatchEvent('reloadStart');
|
|
13138
|
+
this._fireEvent('reloadStart');
|
|
13139
|
+
// Fetch fresh remote data
|
|
13140
|
+
return this._remoteModule
|
|
13141
|
+
.fetchData()
|
|
13142
|
+
.then(function (items) {
|
|
13143
|
+
// Clear existing options
|
|
13144
|
+
_this._clearExistingOptions();
|
|
13145
|
+
// Update state with new items
|
|
13146
|
+
return _this._state.setItems(items).then(function () {
|
|
13147
|
+
// Generate new options HTML
|
|
13148
|
+
_this._generateOptionsHtml(_this._element);
|
|
13149
|
+
// Update the dropdown
|
|
13150
|
+
_this._updateDropdownWithNewOptions();
|
|
13151
|
+
// Sync selection state from native select
|
|
13152
|
+
_this._syncSelectionFromNative();
|
|
13153
|
+
// Update visual display
|
|
13154
|
+
_this.updateSelectedOptionDisplay();
|
|
13155
|
+
_this._updateSelectedOptionClass();
|
|
13156
|
+
// Update select all button state if applicable
|
|
13157
|
+
if (_this._config.multiple && _this._config.enableSelectAll) {
|
|
13158
|
+
_this.updateSelectAllButtonState();
|
|
13159
|
+
}
|
|
13160
|
+
// Dispatch reload complete event
|
|
13161
|
+
_this._dispatchEvent('reloadComplete');
|
|
13162
|
+
_this._fireEvent('reloadComplete');
|
|
13163
|
+
});
|
|
13164
|
+
})
|
|
13165
|
+
.catch(function (error) {
|
|
13166
|
+
console.error('Error reloading remote data:', error);
|
|
13167
|
+
// Dispatch reload error event with error details
|
|
13168
|
+
_this._dispatchEvent('reloadError', { error: error });
|
|
13169
|
+
_this._fireEvent('reloadError', { error: error });
|
|
13170
|
+
// Re-throw error so caller can handle it
|
|
13171
|
+
throw error;
|
|
13172
|
+
});
|
|
13034
13173
|
};
|
|
13035
13174
|
/**
|
|
13036
13175
|
* Refresh the visual display and state without rebuilding options
|
|
13176
|
+
* For remote selects, refetches data from the server
|
|
13037
13177
|
* @public
|
|
13038
13178
|
*/
|
|
13039
13179
|
KTSelect.prototype.refresh = function () {
|
|
13040
|
-
|
|
13041
|
-
|
|
13042
|
-
|
|
13043
|
-
|
|
13044
|
-
|
|
13045
|
-
|
|
13046
|
-
|
|
13180
|
+
var _this = this;
|
|
13181
|
+
// For remote selects, refetch data
|
|
13182
|
+
if (this._config.remote && this._remoteModule) {
|
|
13183
|
+
this._remoteModule
|
|
13184
|
+
.fetchData()
|
|
13185
|
+
.then(function (items) {
|
|
13186
|
+
// Clear existing options
|
|
13187
|
+
_this._clearExistingOptions();
|
|
13188
|
+
// Add new options
|
|
13189
|
+
items.forEach(function (item) {
|
|
13190
|
+
var option = document.createElement('option');
|
|
13191
|
+
option.value = item.id;
|
|
13192
|
+
option.textContent = item.title;
|
|
13193
|
+
if (item.disabled)
|
|
13194
|
+
option.disabled = true;
|
|
13195
|
+
_this._element.appendChild(option);
|
|
13196
|
+
});
|
|
13197
|
+
// Rebuild dropdown
|
|
13198
|
+
_this._rebuildOptionsFromNative();
|
|
13199
|
+
// Sync selection state
|
|
13200
|
+
_this._syncSelectionFromNative();
|
|
13201
|
+
// Reapply ARIA attributes
|
|
13202
|
+
_this._setAriaAttributes();
|
|
13203
|
+
// Dispatch refreshed event
|
|
13204
|
+
_this._dispatchEvent('refreshed');
|
|
13205
|
+
_this._fireEvent('refreshed');
|
|
13206
|
+
})
|
|
13207
|
+
.catch(function (error) {
|
|
13208
|
+
console.error('Error refreshing remote data:', error);
|
|
13209
|
+
_this._dispatchEvent('refreshError');
|
|
13210
|
+
_this._fireEvent('refreshError');
|
|
13211
|
+
});
|
|
13212
|
+
}
|
|
13213
|
+
else {
|
|
13214
|
+
// For static selects, just sync visual state
|
|
13215
|
+
this._syncSelectionFromNative();
|
|
13216
|
+
// Reapply ARIA attributes
|
|
13217
|
+
this._setAriaAttributes();
|
|
13218
|
+
// Dispatch refreshed event
|
|
13219
|
+
this._dispatchEvent('refreshed');
|
|
13220
|
+
this._fireEvent('refreshed');
|
|
13221
|
+
}
|
|
13047
13222
|
};
|
|
13048
13223
|
/**
|
|
13049
13224
|
* ========================================================================
|
|
@@ -18447,6 +18622,11 @@ var KTSelectState = /** @class */ (function () {
|
|
|
18447
18622
|
return this._config;
|
|
18448
18623
|
};
|
|
18449
18624
|
KTSelectState.prototype.setSelectedOptions = function (value) {
|
|
18625
|
+
// Handle empty array case first to prevent undefined elements
|
|
18626
|
+
if (Array.isArray(value) && value.length === 0) {
|
|
18627
|
+
this._selectedOptions = [];
|
|
18628
|
+
return;
|
|
18629
|
+
}
|
|
18450
18630
|
if (this._config.multiple &&
|
|
18451
18631
|
typeof value === 'string' &&
|
|
18452
18632
|
!this._selectedOptions.includes(value)) {
|