@keenthemes/ktui 1.0.13 → 1.0.14

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.
Files changed (34) hide show
  1. package/dist/ktui.js +124 -69
  2. package/dist/ktui.min.js +1 -1
  3. package/dist/ktui.min.js.map +1 -1
  4. package/dist/styles.css +4 -2
  5. package/examples/select/modal.html +0 -3
  6. package/lib/cjs/components/datatable/datatable.js +13 -10
  7. package/lib/cjs/components/datatable/datatable.js.map +1 -1
  8. package/lib/cjs/components/select/combobox.js.map +1 -1
  9. package/lib/cjs/components/select/config.js +12 -5
  10. package/lib/cjs/components/select/config.js.map +1 -1
  11. package/lib/cjs/components/select/select.js +99 -52
  12. package/lib/cjs/components/select/select.js.map +1 -1
  13. package/lib/cjs/components/select/templates.js +0 -2
  14. package/lib/cjs/components/select/templates.js.map +1 -1
  15. package/lib/cjs/components/select/utils.js.map +1 -1
  16. package/lib/esm/components/datatable/datatable.js +13 -10
  17. package/lib/esm/components/datatable/datatable.js.map +1 -1
  18. package/lib/esm/components/select/combobox.js.map +1 -1
  19. package/lib/esm/components/select/config.js +12 -5
  20. package/lib/esm/components/select/config.js.map +1 -1
  21. package/lib/esm/components/select/select.js +99 -52
  22. package/lib/esm/components/select/select.js.map +1 -1
  23. package/lib/esm/components/select/templates.js +0 -2
  24. package/lib/esm/components/select/templates.js.map +1 -1
  25. package/lib/esm/components/select/utils.js.map +1 -1
  26. package/package.json +1 -1
  27. package/src/components/datatable/datatable.ts +13 -10
  28. package/src/components/select/combobox.ts +1 -1
  29. package/src/components/select/config.ts +14 -5
  30. package/src/components/select/select.css +3 -1
  31. package/src/components/select/select.ts +105 -51
  32. package/src/components/select/templates.ts +1 -5
  33. package/src/components/select/utils.ts +1 -1
  34. package/src/components/toast/toast.css +1 -1
package/dist/ktui.js CHANGED
@@ -8436,16 +8436,19 @@ var KTDataTable = /** @class */ (function (_super) {
8436
8436
  if (!_sizeElement) {
8437
8437
  return _sizeElement;
8438
8438
  }
8439
- // Create <option> elements for each page size option
8440
- var options = this._config.pageSizes.map(function (size) {
8441
- var option = document.createElement('option');
8442
- option.value = String(size);
8443
- option.text = String(size);
8444
- option.selected = _this.getState().pageSize === size;
8445
- return option;
8446
- });
8447
- // Add the <option> elements to the provided element
8448
- _sizeElement.append.apply(_sizeElement, options);
8439
+ // Wait for the element to be attached to the DOM
8440
+ setTimeout(function () {
8441
+ // Create <option> elements for each page size option
8442
+ var options = _this._config.pageSizes.map(function (size) {
8443
+ var option = document.createElement('option');
8444
+ option.value = String(size);
8445
+ option.text = String(size);
8446
+ option.selected = _this.getState().pageSize === size;
8447
+ return option;
8448
+ });
8449
+ // Add the <option> elements to the provided element
8450
+ _sizeElement.append.apply(_sizeElement, options);
8451
+ }, 100);
8449
8452
  // Create an event listener for the "change" event on the element
8450
8453
  var _pageSizeControlsEvent = function (event) {
8451
8454
  // When the element changes, reload the page with the new page size and page number 1
@@ -11358,6 +11361,7 @@ var KTSelect = /** @class */ (function (_super) {
11358
11361
  _this._dropdownModule = null;
11359
11362
  _this._loadMoreIndicator = null;
11360
11363
  _this._typeToSearchBuffer = new utils_1.TypeToSearchBuffer();
11364
+ _this._mutationObserver = null;
11361
11365
  // Search debounce timeout
11362
11366
  _this._searchDebounceTimeout = null;
11363
11367
  // Store original options HTML for restoring after search
@@ -11640,6 +11644,7 @@ var KTSelect = /** @class */ (function (_super) {
11640
11644
  this._setAriaAttributes();
11641
11645
  // Attach event listeners after all modules are initialized
11642
11646
  this._attachEventListeners();
11647
+ this._observeNativeSelect();
11643
11648
  };
11644
11649
  /**
11645
11650
  * Creates the HTML structure for the select component
@@ -11655,7 +11660,13 @@ var KTSelect = /** @class */ (function (_super) {
11655
11660
  wrapperElement.appendChild(displayElement);
11656
11661
  // Move classes from original select to display element
11657
11662
  if (this._element.classList.length > 0) {
11658
- (_a = displayElement.classList).add.apply(_a, Array.from(this._element.classList));
11663
+ // Exclude kt-select class from being added to the wrapper element
11664
+ var classes = Array.from(this._element.classList).filter(function (className) { return className !== 'kt-select'; });
11665
+ (_a = wrapperElement.classList).add.apply(_a, classes);
11666
+ // If element has class kt-select, move it to display element
11667
+ if (this._element.classList.contains('kt-select')) {
11668
+ displayElement.classList.add('kt-select');
11669
+ }
11659
11670
  this._element.className = '';
11660
11671
  }
11661
11672
  // Create an empty dropdown first (without options) using template
@@ -11689,7 +11700,7 @@ var KTSelect = /** @class */ (function (_super) {
11689
11700
  wrapperElement.appendChild(dropdownElement);
11690
11701
  // Insert after the original element
11691
11702
  this._element.after(wrapperElement);
11692
- this._element.style.display = 'none';
11703
+ this._element.classList.add('hidden');
11693
11704
  };
11694
11705
  /**
11695
11706
  * Setup all element references after DOM is created
@@ -12040,62 +12051,34 @@ var KTSelect = /** @class */ (function (_super) {
12040
12051
  }
12041
12052
  return; // Nothing to display on if the element is missing
12042
12053
  }
12043
- // 1. Custom render function takes highest precedence
12044
12054
  if (typeof this._config.renderSelected === 'function') {
12045
12055
  valueDisplayEl.innerHTML = this._config.renderSelected(selectedOptions);
12046
- return;
12047
- }
12048
- // 2. Custom displayTemplate string
12049
- // Check if a custom display template string is provided directly in config or via config.templates
12050
- var customDisplayTemplateString = this._config.displayTemplate || (this._config.templates && this._config.templates.display);
12051
- if (customDisplayTemplateString) {
12052
- // If tags are enabled and items are selected, the tags module handles display, so clear the main display area.
12053
- if (tagsEnabled && selectedOptions.length > 0) {
12054
- valueDisplayEl.innerHTML = '';
12055
- }
12056
- else {
12057
- // Otherwise, render the custom display template.
12058
- // If no options are selected, renderDisplayTemplateForSelected should handle showing a placeholder if the template supports it,
12059
- // or we might need a separate placeholder rendering for custom templates if they don't handle empty selection.
12060
- // For now, assume renderDisplayTemplateForSelected handles it or shows selected text.
12061
- valueDisplayEl.innerHTML = this.renderDisplayTemplateForSelected(selectedOptions);
12062
- }
12063
- return;
12064
- }
12065
- // 3. Default template behavior (no custom function or string template)
12066
- var textContainer = valueDisplayEl.querySelector('[data-kt-text-container="true"]');
12067
- if (tagsEnabled && selectedOptions.length > 0) {
12068
- // Tags are active and have content, clear the text container if it exists,
12069
- // or the whole display if it doesn't (though it should with default template).
12070
- if (textContainer) {
12071
- textContainer.innerHTML = '';
12072
- }
12073
- else {
12074
- valueDisplayEl.innerHTML = ''; // Fallback: clear entire display area
12075
- }
12076
- }
12077
- else if (selectedOptions.length === 0) {
12078
- // No options selected: display placeholder text in the text container.
12079
- var placeholderTemplate = templates_1.defaultTemplates.placeholder(this._config);
12080
- var placeholderText = placeholderTemplate.textContent || ''; // Get text from placeholder element
12081
- if (textContainer) {
12082
- textContainer.innerHTML = placeholderText;
12083
- }
12084
- else {
12085
- // Fallback: If no text container, replace children of valueDisplayEl with the placeholder element itself.
12086
- // This ensures the placeholder (which might have its own structure/classes) is displayed.
12087
- valueDisplayEl.replaceChildren(placeholderTemplate);
12088
- }
12089
12056
  }
12090
12057
  else {
12091
- // Options are selected, and tags are not enabled (or no selected options for tags):
12092
- // Render normal selected text in the text container.
12093
- var content = this.getSelectedOptionsText();
12094
- if (textContainer) {
12095
- textContainer.innerHTML = content;
12058
+ if (selectedOptions.length === 0) {
12059
+ // No options selected: display placeholder.
12060
+ // This runs if tags are off, OR if tags are on but no items are selected (tags module would have cleared tags).
12061
+ var placeholderEl = templates_1.defaultTemplates.placeholder(this._config);
12062
+ valueDisplayEl.replaceChildren(placeholderEl);
12096
12063
  }
12097
12064
  else {
12098
- valueDisplayEl.innerHTML = content; // Fallback: set content on whole display area
12065
+ // Options are selected.
12066
+ if (tagsEnabled) {
12067
+ // Tags are enabled AND options are selected: tags module has rendered them.
12068
+ // Clear valueDisplayEl as tags are the primary display.
12069
+ valueDisplayEl.innerHTML = '';
12070
+ }
12071
+ else {
12072
+ // Tags are not enabled AND options are selected: render normal text display.
12073
+ var content = '';
12074
+ if (this._config.displayTemplate) {
12075
+ content = this.renderDisplayTemplateForSelected(this.getSelectedOptions());
12076
+ }
12077
+ else {
12078
+ content = this.getSelectedOptionsText();
12079
+ }
12080
+ valueDisplayEl.innerHTML = content;
12081
+ }
12099
12082
  }
12100
12083
  }
12101
12084
  };
@@ -12756,6 +12739,73 @@ var KTSelect = /** @class */ (function (_super) {
12756
12739
  KTSelect.prototype.getDisplayElement = function () {
12757
12740
  return this._displayElement;
12758
12741
  };
12742
+ KTSelect.prototype._observeNativeSelect = function () {
12743
+ var _this = this;
12744
+ if (this._mutationObserver)
12745
+ return; // Prevent double observers
12746
+ this._mutationObserver = new MutationObserver(function (mutations) {
12747
+ var needsRebuild = false;
12748
+ var needsSelectionSync = false;
12749
+ for (var _i = 0, mutations_1 = mutations; _i < mutations_1.length; _i++) {
12750
+ var mutation = mutations_1[_i];
12751
+ if (mutation.type === 'childList') {
12752
+ // Option(s) added or removed
12753
+ needsRebuild = true;
12754
+ }
12755
+ else if (mutation.type === 'attributes' && mutation.target instanceof HTMLOptionElement) {
12756
+ if (mutation.attributeName === 'selected') {
12757
+ needsSelectionSync = true;
12758
+ }
12759
+ }
12760
+ }
12761
+ if (needsRebuild) {
12762
+ // Rebuild the custom dropdown options
12763
+ _this._rebuildOptionsFromNative();
12764
+ }
12765
+ if (needsSelectionSync) {
12766
+ _this._syncSelectionFromNative();
12767
+ }
12768
+ });
12769
+ this._mutationObserver.observe(this._element, {
12770
+ childList: true,
12771
+ attributes: true,
12772
+ subtree: true,
12773
+ attributeFilter: ['selected'],
12774
+ });
12775
+ };
12776
+ KTSelect.prototype._rebuildOptionsFromNative = function () {
12777
+ var _this = this;
12778
+ // Remove and rebuild the custom dropdown options from the native select
12779
+ if (this._dropdownContentElement) {
12780
+ var optionsContainer_1 = this._dropdownContentElement.querySelector('[data-kt-select-options]');
12781
+ if (optionsContainer_1) {
12782
+ optionsContainer_1.innerHTML = '';
12783
+ var options = Array.from(this._element.querySelectorAll('option'));
12784
+ options.forEach(function (optionElement) {
12785
+ if (optionElement.value === '' &&
12786
+ optionElement.textContent.trim() === '') {
12787
+ return;
12788
+ }
12789
+ var selectOption = new option_1.KTSelectOption(optionElement, _this._config);
12790
+ var renderedOption = selectOption.render();
12791
+ optionsContainer_1.appendChild(renderedOption);
12792
+ });
12793
+ // Update internal references
12794
+ this._options = this._wrapperElement.querySelectorAll('[data-kt-select-option]');
12795
+ }
12796
+ }
12797
+ // Sync selection after rebuilding
12798
+ this._syncSelectionFromNative();
12799
+ this.updateSelectedOptionDisplay();
12800
+ this._updateSelectedOptionClass();
12801
+ };
12802
+ KTSelect.prototype._syncSelectionFromNative = function () {
12803
+ // Sync internal state from the native select's selected options
12804
+ var selected = Array.from(this._element.querySelectorAll('option:checked')).map(function (opt) { return opt.value; });
12805
+ this._state.setSelectedOptions(this._config.multiple ? selected : selected[0] || '');
12806
+ this.updateSelectedOptionDisplay();
12807
+ this._updateSelectedOptionClass();
12808
+ };
12759
12809
  /**
12760
12810
  * ========================================================================
12761
12811
  * STATIC METHODS
@@ -16174,8 +16224,6 @@ exports.defaultTemplates = {
16174
16224
  wrapper: function (config) {
16175
16225
  var html = getTemplateStrings(config).wrapper.replace('{{class}}', config.wrapperClass || '');
16176
16226
  var element = stringToElement(html);
16177
- element.setAttribute('data-kt-select-combobox', config.combobox ? 'true' : 'false');
16178
- element.setAttribute('data-kt-select-tags', config.tags ? 'true' : 'false');
16179
16227
  return element;
16180
16228
  },
16181
16229
  /**
@@ -17477,6 +17525,7 @@ exports.DefaultConfig = {
17477
17525
  paginationLimitParam: 'limit', // Parameter name for items per page
17478
17526
  paginationTotalParam: 'total', // Parameter name for total items
17479
17527
  // Selection Behavior
17528
+ allowClear: false, // Allow clearing the selection (if true, an empty value can be set)
17480
17529
  multiple: false, // Enable/disable multi-select
17481
17530
  maxSelections: null, // Maximum number of selections allowed in multi-select mode (null for unlimited)
17482
17531
  disabled: false, // Disable the select component
@@ -17581,11 +17630,17 @@ var KTSelectState = /** @class */ (function () {
17581
17630
  return this._config.items || [];
17582
17631
  };
17583
17632
  KTSelectState.prototype.setItemsFromOptions = function (options) {
17584
- this._config.items = options.map(function (option) { return ({
17585
- id: option.value,
17586
- title: option.textContent || '',
17587
- // Add other properties from option element if needed
17588
- }); });
17633
+ this._config.items = options.map(function (option) {
17634
+ var item = {
17635
+ id: option.value,
17636
+ title: option.textContent || option.value, // Use value as fallback for title
17637
+ // 'selected' property will be definitively set by _preSelectOptions
17638
+ disabled: option.disabled,
17639
+ };
17640
+ return item;
17641
+ });
17642
+ // The 'selected' status of these items and the overall component selection state
17643
+ // are now fully managed by _preSelectOptions in KTSelect during initialization.
17589
17644
  };
17590
17645
  KTSelectState.prototype.getConfig = function () {
17591
17646
  return this._config;