@smilodon/core 1.0.10 → 1.0.12

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/index.cjs CHANGED
@@ -865,6 +865,13 @@ const defaultConfig = {
865
865
  preloadAdjacent: true,
866
866
  scrollRestoration: 'auto',
867
867
  },
868
+ expandable: {
869
+ enabled: false,
870
+ collapsedHeight: '300px',
871
+ expandedHeight: '500px',
872
+ expandLabel: 'Show more',
873
+ collapseLabel: 'Show less',
874
+ },
868
875
  callbacks: {},
869
876
  enabled: true,
870
877
  searchable: false,
@@ -954,10 +961,13 @@ class EnhancedSelect extends HTMLElement {
954
961
  this._hasError = false;
955
962
  this._errorMessage = '';
956
963
  this._boundArrowClick = null;
964
+ console.log('[EnhancedSelect] Constructor called');
957
965
  this._shadow = this.attachShadow({ mode: 'open' });
966
+ console.log('[EnhancedSelect] Shadow root attached:', this._shadow);
958
967
  this._uniqueId = `enhanced-select-${Math.random().toString(36).substr(2, 9)}`;
959
968
  // Merge global config with component-level config
960
969
  this._config = selectConfig.getConfig();
970
+ console.log('[EnhancedSelect] Config loaded');
961
971
  // Initialize state
962
972
  this._state = {
963
973
  isOpen: false,
@@ -975,21 +985,36 @@ class EnhancedSelect extends HTMLElement {
975
985
  lastScrollPosition: 0,
976
986
  lastNotifiedQuery: null,
977
987
  lastNotifiedResultCount: 0,
988
+ isExpanded: false,
978
989
  };
990
+ console.log('[EnhancedSelect] State initialized');
979
991
  // Create DOM structure
980
992
  this._container = this._createContainer();
993
+ console.log('[EnhancedSelect] Container created:', this._container);
981
994
  this._inputContainer = this._createInputContainer();
995
+ console.log('[EnhancedSelect] Input container created');
982
996
  this._input = this._createInput();
997
+ console.log('[EnhancedSelect] Input created:', this._input);
983
998
  this._arrowContainer = this._createArrowContainer();
999
+ console.log('[EnhancedSelect] Arrow container created');
984
1000
  this._dropdown = this._createDropdown();
1001
+ console.log('[EnhancedSelect] Dropdown created');
985
1002
  this._optionsContainer = this._createOptionsContainer();
1003
+ console.log('[EnhancedSelect] Options container created');
986
1004
  this._liveRegion = this._createLiveRegion();
1005
+ console.log('[EnhancedSelect] Live region created');
987
1006
  this._assembleDOM();
1007
+ console.log('[EnhancedSelect] DOM assembled');
988
1008
  this._initializeStyles();
1009
+ console.log('[EnhancedSelect] Styles initialized');
989
1010
  this._attachEventListeners();
1011
+ console.log('[EnhancedSelect] Event listeners attached');
990
1012
  this._initializeObservers();
1013
+ console.log('[EnhancedSelect] Observers initialized');
1014
+ console.log('[EnhancedSelect] Constructor complete, shadow DOM children:', this._shadow.children.length);
991
1015
  }
992
1016
  connectedCallback() {
1017
+ console.log('[EnhancedSelect] connectedCallback called');
993
1018
  // Load initial data if server-side is enabled
994
1019
  if (this._config.serverSide.enabled && this._config.serverSide.initialSelectedValues) {
995
1020
  this._loadInitialSelectedItems();
@@ -998,6 +1023,7 @@ class EnhancedSelect extends HTMLElement {
998
1023
  if (this._config.callbacks.onOpen) {
999
1024
  this._config.callbacks.onOpen();
1000
1025
  }
1026
+ console.log('[EnhancedSelect] connectedCallback complete');
1001
1027
  }
1002
1028
  disconnectedCallback() {
1003
1029
  // Cleanup observers
@@ -1095,22 +1121,43 @@ class EnhancedSelect extends HTMLElement {
1095
1121
  return container;
1096
1122
  }
1097
1123
  _assembleDOM() {
1124
+ console.log('[EnhancedSelect] _assembleDOM: Starting DOM assembly');
1125
+ console.log('[EnhancedSelect] _assembleDOM: Elements to assemble:', {
1126
+ inputContainer: !!this._inputContainer,
1127
+ input: !!this._input,
1128
+ arrowContainer: !!this._arrowContainer,
1129
+ container: !!this._container,
1130
+ dropdown: !!this._dropdown,
1131
+ optionsContainer: !!this._optionsContainer,
1132
+ shadow: !!this._shadow,
1133
+ liveRegion: !!this._liveRegion
1134
+ });
1098
1135
  this._inputContainer.appendChild(this._input);
1136
+ console.log('[EnhancedSelect] _assembleDOM: Appended input to inputContainer');
1099
1137
  if (this._arrowContainer) {
1100
1138
  this._inputContainer.appendChild(this._arrowContainer);
1139
+ console.log('[EnhancedSelect] _assembleDOM: Appended arrowContainer to inputContainer');
1101
1140
  }
1102
1141
  this._container.appendChild(this._inputContainer);
1142
+ console.log('[EnhancedSelect] _assembleDOM: Appended inputContainer to container');
1103
1143
  this._dropdown.appendChild(this._optionsContainer);
1144
+ console.log('[EnhancedSelect] _assembleDOM: Appended optionsContainer to dropdown');
1104
1145
  this._container.appendChild(this._dropdown);
1146
+ console.log('[EnhancedSelect] _assembleDOM: Appended dropdown to container');
1105
1147
  this._shadow.appendChild(this._container);
1148
+ console.log('[EnhancedSelect] _assembleDOM: Appended container to shadow root');
1106
1149
  if (this._liveRegion) {
1107
1150
  this._shadow.appendChild(this._liveRegion);
1151
+ console.log('[EnhancedSelect] _assembleDOM: Appended liveRegion to shadow root');
1108
1152
  }
1153
+ console.log('[EnhancedSelect] _assembleDOM: Shadow root children count:', this._shadow.children.length);
1154
+ console.log('[EnhancedSelect] _assembleDOM: Shadow root HTML length:', this._shadow.innerHTML.length);
1109
1155
  // Set ARIA relationships
1110
1156
  const listboxId = `${this._uniqueId}-listbox`;
1111
1157
  this._dropdown.id = listboxId;
1112
1158
  this._input.setAttribute('aria-controls', listboxId);
1113
1159
  this._input.setAttribute('aria-owns', listboxId);
1160
+ console.log('[EnhancedSelect] _assembleDOM: Set ARIA relationships with listboxId:', listboxId);
1114
1161
  }
1115
1162
  _initializeStyles() {
1116
1163
  const style = document.createElement('style');
@@ -1267,7 +1314,7 @@ class EnhancedSelect extends HTMLElement {
1267
1314
  right: 0;
1268
1315
  margin-top: 4px;
1269
1316
  max-height: 300px;
1270
- overflow-y: auto;
1317
+ overflow: hidden;
1271
1318
  background: var(--select-dropdown-bg, white);
1272
1319
  border: 1px solid var(--select-dropdown-border, #ccc);
1273
1320
  border-radius: var(--select-border-radius, 4px);
@@ -1277,6 +1324,8 @@ class EnhancedSelect extends HTMLElement {
1277
1324
 
1278
1325
  .options-container {
1279
1326
  position: relative;
1327
+ max-height: 300px;
1328
+ overflow: auto;
1280
1329
  transition: opacity 0.2s ease-in-out;
1281
1330
  }
1282
1331
 
@@ -1438,7 +1487,11 @@ class EnhancedSelect extends HTMLElement {
1438
1487
  min-height: 44px;
1439
1488
  }
1440
1489
  `;
1490
+ console.log('[EnhancedSelect] _initializeStyles: Created style element, content length:', style.textContent?.length || 0);
1491
+ console.log('[EnhancedSelect] _initializeStyles: Appending style to shadow root...');
1441
1492
  this._shadow.appendChild(style);
1493
+ console.log('[EnhancedSelect] _initializeStyles: Style appended, shadow root children:', this._shadow.children.length);
1494
+ console.log('[EnhancedSelect] _initializeStyles: Shadow root has style element:', !!this._shadow.querySelector('style'));
1442
1495
  }
1443
1496
  _attachEventListeners() {
1444
1497
  // Arrow click handler
@@ -2014,21 +2067,27 @@ class EnhancedSelect extends HTMLElement {
2014
2067
  * Set items to display in the select
2015
2068
  */
2016
2069
  setItems(items) {
2070
+ console.log('[EnhancedSelect] setItems called with', items?.length || 0, 'items');
2071
+ console.log('[EnhancedSelect] Items:', items);
2017
2072
  const previousLength = this._state.loadedItems.length;
2018
2073
  this._state.loadedItems = items;
2019
2074
  // If grouped items exist, flatten them to items
2020
2075
  if (this._state.groupedItems.length > 0) {
2021
2076
  this._state.loadedItems = this._state.groupedItems.flatMap(group => group.options);
2077
+ console.log('[EnhancedSelect] Flattened grouped items to', this._state.loadedItems.length, 'items');
2022
2078
  }
2023
2079
  const newLength = this._state.loadedItems.length;
2080
+ console.log('[EnhancedSelect] State.loadedItems updated:', previousLength, '→', newLength);
2024
2081
  // When infinite scroll is active (preserveScrollPosition = true),
2025
2082
  // we need to maintain scroll position during the update
2026
2083
  if (this._state.preserveScrollPosition && this._dropdown) {
2027
2084
  const targetScrollTop = this._state.lastScrollPosition;
2085
+ console.log('[EnhancedSelect] Preserving scroll position:', targetScrollTop);
2028
2086
  // Only clear loading if we actually got more items
2029
2087
  if (newLength > previousLength) {
2030
2088
  this._state.isBusy = false;
2031
2089
  }
2090
+ console.log('[EnhancedSelect] Calling _renderOptions (with scroll preservation)...');
2032
2091
  this._renderOptions();
2033
2092
  // Restore the exact scrollTop we had before loading
2034
2093
  // so the previously visible items stay in place and
@@ -2048,8 +2107,10 @@ class EnhancedSelect extends HTMLElement {
2048
2107
  else {
2049
2108
  // Normal update - just render normally
2050
2109
  this._state.isBusy = false;
2110
+ console.log('[EnhancedSelect] Calling _renderOptions (normal)...');
2051
2111
  this._renderOptions();
2052
2112
  }
2113
+ console.log('[EnhancedSelect] setItems complete');
2053
2114
  }
2054
2115
  /**
2055
2116
  * Set grouped items
@@ -2213,11 +2274,21 @@ class EnhancedSelect extends HTMLElement {
2213
2274
  * Render options based on current state
2214
2275
  */
2215
2276
  _renderOptions() {
2277
+ console.log('[EnhancedSelect] _renderOptions called');
2278
+ console.log('[EnhancedSelect] State:', {
2279
+ loadedItems: this._state.loadedItems.length,
2280
+ groupedItems: this._state.groupedItems.length,
2281
+ isOpen: this._state.isOpen,
2282
+ isSearching: this._state.isSearching,
2283
+ searchQuery: this._state.searchQuery,
2284
+ isBusy: this._state.isBusy
2285
+ });
2216
2286
  // Cleanup observer
2217
2287
  if (this._loadMoreTrigger && this._intersectionObserver) {
2218
2288
  this._intersectionObserver.unobserve(this._loadMoreTrigger);
2219
2289
  }
2220
2290
  // Clear options container
2291
+ console.log('[EnhancedSelect] Clearing options container, previous children:', this._optionsContainer.children.length);
2221
2292
  this._optionsContainer.innerHTML = '';
2222
2293
  // Ensure dropdown only contains options container (cleanup legacy direct children)
2223
2294
  // We need to preserve optionsContainer, so we can't just clear dropdown.innerHTML
@@ -2230,6 +2301,7 @@ class EnhancedSelect extends HTMLElement {
2230
2301
  // Ensure dropdown is visible if we are rendering options
2231
2302
  if (this._state.isOpen && this._dropdown.style.display === 'none') {
2232
2303
  this._dropdown.style.display = 'block';
2304
+ console.log('[EnhancedSelect] Dropdown display set to block');
2233
2305
  }
2234
2306
  // Show searching state (exclusive state)
2235
2307
  if (this._state.isSearching) {
@@ -2237,6 +2309,7 @@ class EnhancedSelect extends HTMLElement {
2237
2309
  searching.className = 'searching-state';
2238
2310
  searching.textContent = 'Searching...';
2239
2311
  this._optionsContainer.appendChild(searching);
2312
+ console.log('[EnhancedSelect] Added searching state');
2240
2313
  return;
2241
2314
  }
2242
2315
  const getValue = this._config.serverSide.getValueFromItem || ((item) => item?.value ?? item);
@@ -2245,6 +2318,7 @@ class EnhancedSelect extends HTMLElement {
2245
2318
  const query = this._state.searchQuery.toLowerCase();
2246
2319
  // Handle Grouped Items Rendering (when no search query)
2247
2320
  if (this._state.groupedItems.length > 0 && !query) {
2321
+ console.log('[EnhancedSelect] Rendering grouped items:', this._state.groupedItems.length, 'groups');
2248
2322
  this._state.groupedItems.forEach(group => {
2249
2323
  const header = document.createElement('div');
2250
2324
  header.className = 'group-header';
@@ -2274,6 +2348,7 @@ class EnhancedSelect extends HTMLElement {
2274
2348
  }
2275
2349
  else {
2276
2350
  // Normal rendering (flat list or filtered)
2351
+ console.log('[EnhancedSelect] Rendering flat list:', this._state.loadedItems.length, 'items');
2277
2352
  let hasRenderedItems = false;
2278
2353
  this._state.loadedItems.forEach((item, index) => {
2279
2354
  // Apply filter if query exists
@@ -2290,6 +2365,7 @@ class EnhancedSelect extends HTMLElement {
2290
2365
  hasRenderedItems = true;
2291
2366
  this._renderSingleOption(item, index, getValue, getLabel);
2292
2367
  });
2368
+ console.log('[EnhancedSelect] Rendered', hasRenderedItems ? 'items' : 'no items');
2293
2369
  if (!hasRenderedItems && !this._state.isBusy) {
2294
2370
  const empty = document.createElement('div');
2295
2371
  empty.className = 'empty-state';
@@ -2300,6 +2376,7 @@ class EnhancedSelect extends HTMLElement {
2300
2376
  empty.textContent = 'No options available';
2301
2377
  }
2302
2378
  this._optionsContainer.appendChild(empty);
2379
+ console.log('[EnhancedSelect] Added empty state');
2303
2380
  }
2304
2381
  }
2305
2382
  // Append Busy Indicator if busy
@@ -2317,11 +2394,13 @@ class EnhancedSelect extends HTMLElement {
2317
2394
  busyBucket.appendChild(message);
2318
2395
  }
2319
2396
  this._optionsContainer.appendChild(busyBucket);
2397
+ console.log('[EnhancedSelect] Added busy bucket');
2320
2398
  }
2321
2399
  // Append Load More Trigger (Button or Sentinel) if enabled and not busy
2322
2400
  else if ((this._config.loadMore.enabled || this._config.infiniteScroll.enabled) && this._state.loadedItems.length > 0) {
2323
2401
  this._addLoadMoreTrigger();
2324
2402
  }
2403
+ console.log('[EnhancedSelect] _renderOptions complete, optionsContainer children:', this._optionsContainer.children.length);
2325
2404
  }
2326
2405
  _renderSingleOption(item, index, getValue, getLabel) {
2327
2406
  const option = document.createElement('div');
@@ -2329,6 +2408,7 @@ class EnhancedSelect extends HTMLElement {
2329
2408
  option.id = `${this._uniqueId}-option-${index}`;
2330
2409
  const value = getValue(item);
2331
2410
  const label = getLabel(item);
2411
+ console.log('[EnhancedSelect] Rendering option', index, ':', { value, label });
2332
2412
  option.textContent = label;
2333
2413
  option.dataset.value = String(value);
2334
2414
  option.dataset.index = String(index); // Also useful for debugging/selectors
@@ -2345,6 +2425,7 @@ class EnhancedSelect extends HTMLElement {
2345
2425
  this._selectOption(index);
2346
2426
  });
2347
2427
  this._optionsContainer.appendChild(option);
2428
+ console.log('[EnhancedSelect] Option', index, 'appended to optionsContainer');
2348
2429
  }
2349
2430
  _addLoadMoreTrigger() {
2350
2431
  const container = document.createElement('div');