@aquera/nile-elements 1.7.2 → 1.7.4

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 (81) hide show
  1. package/README.md +4 -0
  2. package/dist/index-199b0eac.esm.js +1 -0
  3. package/dist/index-f5e587e2.cjs.js +2 -0
  4. package/dist/index-f5e587e2.cjs.js.map +1 -0
  5. package/dist/index.cjs.js +1 -1
  6. package/dist/index.esm.js +1 -1
  7. package/dist/index.js +1203 -768
  8. package/dist/nile-breadcrumb-item/nile-breadcrumb-item.cjs.js +1 -1
  9. package/dist/nile-breadcrumb-item/nile-breadcrumb-item.cjs.js.map +1 -1
  10. package/dist/nile-breadcrumb-item/nile-breadcrumb-item.esm.js +8 -6
  11. package/dist/nile-combobox/group-utils.cjs.js +2 -0
  12. package/dist/nile-combobox/group-utils.cjs.js.map +1 -0
  13. package/dist/nile-combobox/group-utils.esm.js +1 -0
  14. package/dist/nile-combobox/index.cjs.js +1 -1
  15. package/dist/nile-combobox/index.esm.js +1 -1
  16. package/dist/nile-combobox/nile-combobox.cjs.js +1 -1
  17. package/dist/nile-combobox/nile-combobox.cjs.js.map +1 -1
  18. package/dist/nile-combobox/nile-combobox.css.cjs.js +1 -1
  19. package/dist/nile-combobox/nile-combobox.css.cjs.js.map +1 -1
  20. package/dist/nile-combobox/nile-combobox.css.esm.js +77 -4
  21. package/dist/nile-combobox/nile-combobox.esm.js +27 -22
  22. package/dist/nile-combobox/renderer.cjs.js +1 -1
  23. package/dist/nile-combobox/renderer.cjs.js.map +1 -1
  24. package/dist/nile-combobox/renderer.esm.js +84 -42
  25. package/dist/nile-detail/index.cjs.js +1 -1
  26. package/dist/nile-detail/index.esm.js +1 -1
  27. package/dist/nile-detail/nile-detail.cjs.js +1 -1
  28. package/dist/nile-detail/nile-detail.cjs.js.map +1 -1
  29. package/dist/nile-detail/nile-detail.css.cjs.js +1 -1
  30. package/dist/nile-detail/nile-detail.css.cjs.js.map +1 -1
  31. package/dist/nile-detail/nile-detail.css.esm.js +230 -0
  32. package/dist/nile-detail/nile-detail.esm.js +89 -7
  33. package/dist/nile-floating-panel/index.cjs.js +1 -1
  34. package/dist/nile-floating-panel/nile-floating-panel.cjs.js +1 -1
  35. package/dist/nile-inline-sidebar-item/nile-inline-sidebar-item.cjs.js +1 -1
  36. package/dist/nile-inline-sidebar-item/nile-inline-sidebar-item.cjs.js.map +1 -1
  37. package/dist/nile-inline-sidebar-item/nile-inline-sidebar-item.esm.js +1 -1
  38. package/dist/nile-inline-sidebar-item-header/nile-inline-sidebar-item-header.css.cjs.js +1 -1
  39. package/dist/nile-inline-sidebar-item-header/nile-inline-sidebar-item-header.css.cjs.js.map +1 -1
  40. package/dist/nile-inline-sidebar-item-header/nile-inline-sidebar-item-header.css.esm.js +2 -1
  41. package/dist/nile-lite-tooltip/index.cjs.js +1 -1
  42. package/dist/nile-lite-tooltip/nile-lite-tooltip.cjs.js +1 -1
  43. package/dist/src/nile-breadcrumb-item/nile-breadcrumb-item.js +4 -2
  44. package/dist/src/nile-breadcrumb-item/nile-breadcrumb-item.js.map +1 -1
  45. package/dist/src/nile-combobox/group-utils.d.ts +26 -0
  46. package/dist/src/nile-combobox/group-utils.js +140 -0
  47. package/dist/src/nile-combobox/group-utils.js.map +1 -0
  48. package/dist/src/nile-combobox/nile-combobox.css.js +77 -4
  49. package/dist/src/nile-combobox/nile-combobox.css.js.map +1 -1
  50. package/dist/src/nile-combobox/nile-combobox.d.ts +33 -0
  51. package/dist/src/nile-combobox/nile-combobox.js +171 -34
  52. package/dist/src/nile-combobox/nile-combobox.js.map +1 -1
  53. package/dist/src/nile-combobox/renderer.d.ts +4 -0
  54. package/dist/src/nile-combobox/renderer.js +71 -2
  55. package/dist/src/nile-combobox/renderer.js.map +1 -1
  56. package/dist/src/nile-combobox/types.d.ts +30 -0
  57. package/dist/src/nile-combobox/types.js.map +1 -1
  58. package/dist/src/nile-detail/nile-detail.css.js +230 -0
  59. package/dist/src/nile-detail/nile-detail.css.js.map +1 -1
  60. package/dist/src/nile-detail/nile-detail.d.ts +151 -0
  61. package/dist/src/nile-detail/nile-detail.js +829 -4
  62. package/dist/src/nile-detail/nile-detail.js.map +1 -1
  63. package/dist/src/nile-inline-sidebar-item/nile-inline-sidebar-item.js +1 -1
  64. package/dist/src/nile-inline-sidebar-item/nile-inline-sidebar-item.js.map +1 -1
  65. package/dist/src/nile-inline-sidebar-item-header/nile-inline-sidebar-item-header.css.js +2 -1
  66. package/dist/src/nile-inline-sidebar-item-header/nile-inline-sidebar-item-header.css.js.map +1 -1
  67. package/dist/src/version.js +1 -1
  68. package/dist/src/version.js.map +1 -1
  69. package/dist/tsconfig.tsbuildinfo +1 -1
  70. package/package.json +1 -1
  71. package/src/nile-breadcrumb-item/nile-breadcrumb-item.ts +4 -2
  72. package/src/nile-combobox/group-utils.ts +157 -0
  73. package/src/nile-combobox/nile-combobox.css.ts +77 -4
  74. package/src/nile-combobox/nile-combobox.ts +223 -70
  75. package/src/nile-combobox/renderer.ts +119 -2
  76. package/src/nile-combobox/types.ts +36 -0
  77. package/src/nile-detail/nile-detail.css.ts +230 -0
  78. package/src/nile-detail/nile-detail.ts +876 -4
  79. package/src/nile-inline-sidebar-item/nile-inline-sidebar-item.ts +1 -1
  80. package/src/nile-inline-sidebar-item-header/nile-inline-sidebar-item-header.css.ts +2 -1
  81. package/vscode-html-custom-data.json +126 -2
@@ -30,6 +30,7 @@ import { ComboboxSelectionManager } from './selection-manager.js';
30
30
  import { ComboboxSearchManager } from './search-manager.js';
31
31
  import { ComboboxRenderer } from './renderer.js';
32
32
  import { ComboboxPortalManager } from './portal-manager.js';
33
+ import { hasGroups, flattenRows, filterRows, getOptionRows } from './group-utils.js';
33
34
  import { VisibilityManager } from '../utilities/visibility-manager.js';
34
35
  /**
35
36
  * @summary A data-driven combobox with virtualized options, inline search, multi-select tags,
@@ -120,6 +121,14 @@ let NileCombobox = class NileCombobox extends NileElement {
120
121
  this.selectedOptions = [];
121
122
  /** The items displayed after filtering. Renderer reads from this. */
122
123
  this.filteredData = [];
124
+ /**
125
+ * Mixed (header + option) row list, only populated when `data` contains
126
+ * group entries (`type: 'group'`). When non-empty, the listbox renders from
127
+ * this instead of `filteredData`. `filteredData` stays in sync as the
128
+ * option-only projection so existing select-all / strict-match / etc. logic
129
+ * keeps working unchanged.
130
+ */
131
+ this.filteredRows = [];
123
132
  /** The complete unfiltered dataset (preserved for re-filtering). */
124
133
  this.originalData = [];
125
134
  this.showNoResults = false;
@@ -128,6 +137,12 @@ let NileCombobox = class NileCombobox extends NileElement {
128
137
  this.showSelectedOnly = false;
129
138
  this.selectAllChecked = false;
130
139
  this.selectAllIndeterminate = false;
140
+ /**
141
+ * Index into `filteredRows` of the group header that should be pinned at
142
+ * the top of the (virtualized) listbox right now. -1 means none.
143
+ * Recomputed on scroll.
144
+ */
145
+ this.stickyHeaderIndex = -1;
131
146
  // ── Public properties ──
132
147
  this.name = '';
133
148
  this.data = [];
@@ -169,6 +184,13 @@ let NileCombobox = class NileCombobox extends NileElement {
169
184
  * non-disabled options (respects the active search filter).
170
185
  */
171
186
  this.selectAllEnabled = false;
187
+ /**
188
+ * When true (default), data-driven group headers stick to the top of the
189
+ * listbox while scrolling through that group's options (Atlassian-style).
190
+ * Works in both plain and virtualized rendering modes. Set to false for
191
+ * inline-only headers that scroll away with their options.
192
+ */
193
+ this.stickyGroupHeader = true;
172
194
  this.portal = false;
173
195
  this.hoist = false;
174
196
  this.placement = 'bottom';
@@ -201,6 +223,7 @@ let NileCombobox = class NileCombobox extends NileElement {
201
223
  this.gridRows = 0;
202
224
  /** Width of each column in horizontal grid mode (px). */
203
225
  this.gridColumnWidth = 160;
226
+ this.lastVirtualizerGrouped = false;
204
227
  }
205
228
  // ── Accessors ──
206
229
  get validity() {
@@ -261,6 +284,51 @@ let NileCombobox = class NileCombobox extends NileElement {
261
284
  get isHorizontalGrid() {
262
285
  return this.gridRows > 0 && this.gridColumns <= 1;
263
286
  }
287
+ /** True when the source data contains at least one group entry. */
288
+ get hasGroupedData() {
289
+ const base = this.originalData.length > 0 ? this.originalData : this.data;
290
+ return hasGroups(base);
291
+ }
292
+ /**
293
+ * Walk filteredRows and find the index of the deepest group header whose
294
+ * virtual position is at or above `scrollTop`. That's the header that
295
+ * should be pinned at the top of the listbox right now.
296
+ */
297
+ updateStickyHeader(scrollTop) {
298
+ if (!this.stickyGroupHeader || !this.hasGroupedData) {
299
+ if (this.stickyHeaderIndex !== -1)
300
+ this.stickyHeaderIndex = -1;
301
+ return;
302
+ }
303
+ let offset = 0;
304
+ let stuck = -1;
305
+ for (let i = 0; i < this.filteredRows.length; i++) {
306
+ const row = this.filteredRows[i];
307
+ const size = row.kind === 'header' ? 32 : 38;
308
+ if (offset > scrollTop)
309
+ break;
310
+ if (row.kind === 'header')
311
+ stuck = i;
312
+ offset += size;
313
+ }
314
+ if (stuck !== this.stickyHeaderIndex)
315
+ this.stickyHeaderIndex = stuck;
316
+ }
317
+ /** Recursively keep only options whose value is in `selectedSet`; drop empty groups. */
318
+ pruneTreeBySelection(items, selectedSet) {
319
+ const out = [];
320
+ for (const item of items) {
321
+ if (item && typeof item === 'object' && item.type === 'group' && Array.isArray(item.options)) {
322
+ const kept = this.pruneTreeBySelection(item.options, selectedSet);
323
+ if (kept.length > 0)
324
+ out.push({ ...item, options: kept });
325
+ }
326
+ else if (selectedSet.has(String(this.getItemValue(item)))) {
327
+ out.push(item);
328
+ }
329
+ }
330
+ return out;
331
+ }
264
332
  get hasActiveFilter() {
265
333
  return !!this.searchValue || this.showSelectedOnly;
266
334
  }
@@ -277,6 +345,9 @@ let NileCombobox = class NileCombobox extends NileElement {
277
345
  if (this.gridColumns > 1) {
278
346
  return Math.ceil(this.filteredData.length / this.gridColumns);
279
347
  }
348
+ if (this.hasGroupedData) {
349
+ return this.filteredRows.length;
350
+ }
280
351
  return this.filteredData.length;
281
352
  }
282
353
  get virtualColumnCount() {
@@ -298,12 +369,20 @@ let NileCombobox = class NileCombobox extends NileElement {
298
369
  else {
299
370
  const virtualizer = this.virtualizerCtrl.getVirtualizer();
300
371
  const count = this.virtualRowCount;
301
- if (virtualizer.options.count !== count) {
372
+ const grouped = this.hasGroupedData;
373
+ const countChanged = virtualizer.options.count !== count;
374
+ const modeChanged = this.lastVirtualizerGrouped !== grouped;
375
+ if (countChanged || modeChanged) {
376
+ const estimateSize = grouped
377
+ ? (index) => (this.filteredRows[index]?.kind === 'header' ? 32 : 38)
378
+ : () => 38;
302
379
  virtualizer.setOptions({
303
380
  ...virtualizer.options,
304
381
  count,
382
+ estimateSize,
305
383
  });
306
384
  virtualizer.measure();
385
+ this.lastVirtualizerGrouped = grouped;
307
386
  }
308
387
  }
309
388
  }
@@ -334,7 +413,10 @@ let NileCombobox = class NileCombobox extends NileElement {
334
413
  }
335
414
  // ── Selection ──
336
415
  syncSelection() {
337
- const items = this.originalData.length > 0 ? this.originalData : this.data;
416
+ const baseData = this.originalData.length > 0 ? this.originalData : this.data;
417
+ const items = this.hasGroupedData
418
+ ? getOptionRows(flattenRows(baseData)).map(r => r.item)
419
+ : baseData;
338
420
  this.selectedOptions = ComboboxSelectionManager.createOptionsFromValues(this.value, items, this.getDisplayText.bind(this), this.renderItemConfig?.getValue);
339
421
  if (!this.multiple) {
340
422
  const label = this.selectedOptions[0]?.getTextLabel() ?? '';
@@ -649,15 +731,34 @@ let NileCombobox = class NileCombobox extends NileElement {
649
731
  }
650
732
  filterOptions(search, preserveScroll = false) {
651
733
  const baseData = this.originalData.length > 0 ? this.originalData : this.data;
652
- let source = baseData;
653
- if (this.showSelectedOnly) {
654
- const selectedValues = Array.isArray(this.value) ? this.value : [this.value];
655
- const selectedSet = new Set(selectedValues.map(v => String(v)));
656
- source = baseData.filter((item) => selectedSet.has(String(this.getItemValue(item))));
734
+ if (this.hasGroupedData) {
735
+ // Grouped path: filter the tree, derive options-only projection.
736
+ let tree = baseData;
737
+ if (this.showSelectedOnly) {
738
+ const selectedValues = Array.isArray(this.value) ? this.value : [this.value];
739
+ const selectedSet = new Set(selectedValues.map(v => String(v)));
740
+ tree = this.pruneTreeBySelection(baseData, selectedSet);
741
+ }
742
+ const { rows } = filterRows(tree, search, this.getSearchText.bind(this));
743
+ this.filteredRows = rows;
744
+ this.filteredData = getOptionRows(rows).map(r => r.item);
745
+ this.showNoResults = this.filteredData.length === 0;
746
+ // Recompute sticky header at current scroll (defaults to top on filter).
747
+ const st = this.scrollElementRef.value?.scrollTop ?? 0;
748
+ this.updateStickyHeader(st);
749
+ }
750
+ else {
751
+ let source = baseData;
752
+ if (this.showSelectedOnly) {
753
+ const selectedValues = Array.isArray(this.value) ? this.value : [this.value];
754
+ const selectedSet = new Set(selectedValues.map(v => String(v)));
755
+ source = baseData.filter((item) => selectedSet.has(String(this.getItemValue(item))));
756
+ }
757
+ const { filteredItems, showNoResults } = this.searchManager.filter(search, source, this.getSearchText.bind(this));
758
+ this.filteredData = filteredItems;
759
+ this.filteredRows = [];
760
+ this.showNoResults = showNoResults;
657
761
  }
658
- const { filteredItems, showNoResults } = this.searchManager.filter(search, source, this.getSearchText.bind(this));
659
- this.filteredData = filteredItems;
660
- this.showNoResults = showNoResults;
661
762
  this.portalManager.resetMeasuredHeight();
662
763
  if (!preserveScroll) {
663
764
  this.resetScrollPosition();
@@ -684,7 +785,10 @@ let NileCombobox = class NileCombobox extends NileElement {
684
785
  return;
685
786
  if (!this.multiple) {
686
787
  if (this.strict) {
687
- const allItems = this.originalData.length > 0 ? this.originalData : this.data;
788
+ const baseData = this.originalData.length > 0 ? this.originalData : this.data;
789
+ const allItems = this.hasGroupedData
790
+ ? getOptionRows(flattenRows(baseData)).map(r => r.item)
791
+ : baseData;
688
792
  const match = allItems.find((item) => this.getDisplayText(item).toLowerCase() === this.searchValue.toLowerCase());
689
793
  if (match) {
690
794
  const val = this.getItemValue(match);
@@ -812,26 +916,14 @@ let NileCombobox = class NileCombobox extends NileElement {
812
916
  if (this.selectedOptions.length === 0)
813
917
  return;
814
918
  this.showSelectedOnly = !this.showSelectedOnly;
815
- if (this.showSelectedOnly) {
919
+ if (this.showSelectedOnly)
816
920
  this.searchValue = '';
817
- const selectedValues = Array.isArray(this.value) ? this.value : [this.value];
818
- this.filteredData = this.originalData.filter((item) => {
819
- const iv = this.getItemValue(item);
820
- return selectedValues.some(val => String(val) === String(iv));
821
- });
822
- }
823
- else {
824
- this.filteredData = [...this.originalData];
825
- }
826
- this.portalManager.resetMeasuredHeight();
827
- this.resetScrollPosition();
828
- this.updateSelectAllState();
829
- this.requestUpdate();
921
+ this.filterOptions(this.searchValue);
830
922
  }
831
923
  clearAll() {
832
924
  this.showSelectedOnly = false;
833
925
  this.value = this.multiple ? [] : '';
834
- this.filteredData = [...this.originalData];
926
+ this.filterOptions('');
835
927
  this.syncSelection();
836
928
  this.emit('nile-change', { value: this.value, name: this.name });
837
929
  this.emit('nile-clear', { value: this.value, name: this.name });
@@ -839,9 +931,10 @@ let NileCombobox = class NileCombobox extends NileElement {
839
931
  }
840
932
  // ── Scroll ──
841
933
  onScroll(e) {
934
+ const target = e.target;
935
+ this.updateStickyHeader(target.scrollTop);
842
936
  if (this.showSelectedOnly)
843
937
  return;
844
- const target = e.target;
845
938
  this.emit('nile-scroll', { scrollTop: target.scrollTop, scrollLeft: target.scrollLeft, name: this.name });
846
939
  if (!this.scrolling) {
847
940
  this.scrolling = true;
@@ -893,8 +986,14 @@ let NileCombobox = class NileCombobox extends NileElement {
893
986
  if (this.originalData.length === 0 && this.data.length > 0) {
894
987
  this.originalData = [...this.data];
895
988
  }
896
- this.filteredData = [...(this.originalData.length > 0 ? this.originalData : this.data)];
897
- this.showNoResults = this.filteredData.length === 0;
989
+ if (this.hasGroupedData) {
990
+ this.filterOptions(this.searchValue);
991
+ }
992
+ else {
993
+ this.filteredData = [...(this.originalData.length > 0 ? this.originalData : this.data)];
994
+ this.filteredRows = [];
995
+ this.showNoResults = this.filteredData.length === 0;
996
+ }
898
997
  await stopAnimations(this);
899
998
  if (this.popup?.popup) {
900
999
  this.popup.popup.style.visibility = 'hidden';
@@ -944,7 +1043,13 @@ let NileCombobox = class NileCombobox extends NileElement {
944
1043
  if (this.data.length > 0 && !this.showSelectedOnly) {
945
1044
  this.originalData = [...this.data];
946
1045
  }
947
- this.filteredData = [...this.data];
1046
+ if (this.hasGroupedData) {
1047
+ this.filterOptions(this.searchValue);
1048
+ }
1049
+ else {
1050
+ this.filteredData = [...this.data];
1051
+ this.filteredRows = [];
1052
+ }
948
1053
  this.syncSelection();
949
1054
  this.updateSelectAllState();
950
1055
  if (!this.optionsLoading && !this.loading && this.data.length === 0) {
@@ -1189,6 +1294,21 @@ let NileCombobox = class NileCombobox extends NileElement {
1189
1294
  </button>
1190
1295
  `;
1191
1296
  }
1297
+ renderStickyHeaderOverlay(grouped, useVirtual) {
1298
+ if (!this.stickyGroupHeader || !grouped || !useVirtual)
1299
+ return html ``;
1300
+ const idx = this.stickyHeaderIndex;
1301
+ if (idx < 0 || idx >= this.filteredRows.length)
1302
+ return html ``;
1303
+ const row = this.filteredRows[idx];
1304
+ if (row.kind !== 'header')
1305
+ return html ``;
1306
+ return html `
1307
+ <div class="combobox__group-sticky-overlay">
1308
+ ${ComboboxRenderer.renderGroupHeader(row)}
1309
+ </div>
1310
+ `;
1311
+ }
1192
1312
  renderListbox() {
1193
1313
  const showAddOption = this.allowCustomValue
1194
1314
  && this.searchValue.trim()
@@ -1204,7 +1324,10 @@ let NileCombobox = class NileCombobox extends NileElement {
1204
1324
  return this.renderHorizontalListbox(!!showAddOption);
1205
1325
  }
1206
1326
  const isGrid = this.gridColumns > 1 || this.isBidirectionalGrid;
1207
- const useVirtual = ComboboxRenderer.shouldUseVirtualizer(this.filteredData, this.gridColumns);
1327
+ const grouped = this.hasGroupedData && !isGrid;
1328
+ const useVirtual = grouped
1329
+ ? this.filteredRows.length >= 5
1330
+ : ComboboxRenderer.shouldUseVirtualizer(this.filteredData, this.gridColumns);
1208
1331
  const virtualizer = this.virtualizerCtrl.getVirtualizer();
1209
1332
  const virtualItems = (useVirtual || isGrid) ? virtualizer.getVirtualItems() : [];
1210
1333
  const totalSize = (useVirtual || isGrid) ? virtualizer.getTotalSize() : 0;
@@ -1225,13 +1348,18 @@ let NileCombobox = class NileCombobox extends NileElement {
1225
1348
  >
1226
1349
  ${this.renderLoader()}
1227
1350
  ${this.renderSelectAll()}
1351
+ ${this.renderStickyHeaderOverlay(grouped, useVirtual)}
1228
1352
  ${this.showNoResults && !this.optionsLoading && !this.loading
1229
1353
  ? this.renderEmptyState()
1230
1354
  : isGrid
1231
1355
  ? ComboboxRenderer.renderVirtualizedGrid(virtualItems, totalSize, this.filteredData, this.value, this.multiple, this.gridColumns, this.getDisplayText.bind(this), this.getItemValue.bind(this), this.optionsLoading || this.loading, this.allowHtmlLabel, this.renderItemConfig?.getDescription ? this.getItemDescription.bind(this) : undefined, this.renderItemConfig?.getPrefix ? this.getItemPrefix.bind(this) : undefined, this.renderItemConfig?.getSuffix ? this.getItemSuffix.bind(this) : undefined, this.isBidirectionalGrid ? this.gridColumnWidth : undefined)
1232
- : useVirtual
1233
- ? ComboboxRenderer.renderVirtualizedOptions(virtualItems, totalSize, this.filteredData, this.value, this.multiple, this.getDisplayText.bind(this), this.getItemValue.bind(this), this.optionsLoading || this.loading, this.allowHtmlLabel, virtualizer.measureElement, this.renderItemConfig?.getDescription ? this.getItemDescription.bind(this) : undefined, this.renderItemConfig?.getPrefix ? this.getItemPrefix.bind(this) : undefined, this.renderItemConfig?.getSuffix ? this.getItemSuffix.bind(this) : undefined)
1234
- : ComboboxRenderer.renderPlainOptions(this.filteredData, this.value, this.multiple, this.getDisplayText.bind(this), this.getItemValue.bind(this), this.showNoResults, this.noResultsMessage, this.optionsLoading || this.loading, this.onScroll.bind(this), this.allowHtmlLabel, this.renderItemConfig?.getDescription ? this.getItemDescription.bind(this) : undefined, this.renderItemConfig?.getPrefix ? this.getItemPrefix.bind(this) : undefined, this.renderItemConfig?.getSuffix ? this.getItemSuffix.bind(this) : undefined, undefined, this.hasActiveFilter ? this.noResultsSubtitle : undefined)}
1356
+ : grouped
1357
+ ? (useVirtual
1358
+ ? ComboboxRenderer.renderRowsVirtualized(virtualItems, totalSize, this.filteredRows, this.value, this.multiple, this.getDisplayText.bind(this), this.getItemValue.bind(this), this.optionsLoading || this.loading, this.allowHtmlLabel, this.renderItemConfig?.getDescription ? this.getItemDescription.bind(this) : undefined, this.renderItemConfig?.getPrefix ? this.getItemPrefix.bind(this) : undefined, this.renderItemConfig?.getSuffix ? this.getItemSuffix.bind(this) : undefined)
1359
+ : ComboboxRenderer.renderRowsPlain(this.filteredRows, this.value, this.multiple, this.getDisplayText.bind(this), this.getItemValue.bind(this), this.showNoResults, this.noResultsMessage, this.optionsLoading || this.loading, this.onScroll.bind(this), this.allowHtmlLabel, this.renderItemConfig?.getDescription ? this.getItemDescription.bind(this) : undefined, this.renderItemConfig?.getPrefix ? this.getItemPrefix.bind(this) : undefined, this.renderItemConfig?.getSuffix ? this.getItemSuffix.bind(this) : undefined, undefined, this.hasActiveFilter ? this.noResultsSubtitle : undefined))
1360
+ : useVirtual
1361
+ ? ComboboxRenderer.renderVirtualizedOptions(virtualItems, totalSize, this.filteredData, this.value, this.multiple, this.getDisplayText.bind(this), this.getItemValue.bind(this), this.optionsLoading || this.loading, this.allowHtmlLabel, virtualizer.measureElement, this.renderItemConfig?.getDescription ? this.getItemDescription.bind(this) : undefined, this.renderItemConfig?.getPrefix ? this.getItemPrefix.bind(this) : undefined, this.renderItemConfig?.getSuffix ? this.getItemSuffix.bind(this) : undefined)
1362
+ : ComboboxRenderer.renderPlainOptions(this.filteredData, this.value, this.multiple, this.getDisplayText.bind(this), this.getItemValue.bind(this), this.showNoResults, this.noResultsMessage, this.optionsLoading || this.loading, this.onScroll.bind(this), this.allowHtmlLabel, this.renderItemConfig?.getDescription ? this.getItemDescription.bind(this) : undefined, this.renderItemConfig?.getPrefix ? this.getItemPrefix.bind(this) : undefined, this.renderItemConfig?.getSuffix ? this.getItemSuffix.bind(this) : undefined, undefined, this.hasActiveFilter ? this.noResultsSubtitle : undefined)}
1235
1363
  ${showAddOption ? html `
1236
1364
  <div @mouseup=${(e) => { e.stopPropagation(); this.addCustomValue(this.searchValue.trim()); }}>
1237
1365
  ${ComboboxRenderer.renderAddCustomOption(this.searchValue.trim(), this.multiple)}
@@ -1375,6 +1503,9 @@ __decorate([
1375
1503
  __decorate([
1376
1504
  state()
1377
1505
  ], NileCombobox.prototype, "filteredData", void 0);
1506
+ __decorate([
1507
+ state()
1508
+ ], NileCombobox.prototype, "filteredRows", void 0);
1378
1509
  __decorate([
1379
1510
  state()
1380
1511
  ], NileCombobox.prototype, "originalData", void 0);
@@ -1396,6 +1527,9 @@ __decorate([
1396
1527
  __decorate([
1397
1528
  state()
1398
1529
  ], NileCombobox.prototype, "selectAllIndeterminate", void 0);
1530
+ __decorate([
1531
+ state()
1532
+ ], NileCombobox.prototype, "stickyHeaderIndex", void 0);
1399
1533
  __decorate([
1400
1534
  property()
1401
1535
  ], NileCombobox.prototype, "name", void 0);
@@ -1470,6 +1604,9 @@ __decorate([
1470
1604
  __decorate([
1471
1605
  property({ type: Boolean, reflect: true, attribute: 'select-all-enabled' })
1472
1606
  ], NileCombobox.prototype, "selectAllEnabled", void 0);
1607
+ __decorate([
1608
+ property({ type: Boolean, reflect: true, attribute: 'sticky-group-header' })
1609
+ ], NileCombobox.prototype, "stickyGroupHeader", void 0);
1473
1610
  __decorate([
1474
1611
  property({ type: Boolean, reflect: true })
1475
1612
  ], NileCombobox.prototype, "portal", void 0);