@smilodon/core 1.3.2 → 1.3.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.
package/dist/index.cjs CHANGED
@@ -546,13 +546,11 @@ class CustomOptionPool {
546
546
  component = pooled.instance;
547
547
  pooled.inUse = true;
548
548
  pooled.lastUsedIndex = index;
549
- console.log(`[CustomOptionPool] Reusing component for index ${index}`);
550
549
  }
551
550
  else {
552
551
  // Create new component
553
552
  try {
554
553
  component = factory(item, index);
555
- console.log(`[CustomOptionPool] Created new component for index ${index}`);
556
554
  // Add to pool if under limit
557
555
  const pool = this._pool.get(factoryKey) || [];
558
556
  if (pool.length < this._maxPoolSize) {
@@ -601,7 +599,6 @@ class CustomOptionPool {
601
599
  const pooled = pool.find(p => p.instance === component);
602
600
  if (pooled) {
603
601
  pooled.inUse = false;
604
- console.log(`[CustomOptionPool] Released component from index ${index}`);
605
602
  break;
606
603
  }
607
604
  }
@@ -610,7 +607,6 @@ class CustomOptionPool {
610
607
  * Release all active components
611
608
  */
612
609
  releaseAll() {
613
- console.log(`[CustomOptionPool] Releasing ${this._activeComponents.size} active components`);
614
610
  const indices = Array.from(this._activeComponents.keys());
615
611
  indices.forEach(index => this.release(index));
616
612
  }
@@ -653,7 +649,6 @@ class CustomOptionPool {
653
649
  clear() {
654
650
  this.releaseAll();
655
651
  this._pool.clear();
656
- console.log('[CustomOptionPool] Pool cleared');
657
652
  }
658
653
  /**
659
654
  * Get pool statistics for debugging
@@ -832,7 +827,6 @@ class OptionRenderer {
832
827
  });
833
828
  }
834
829
  this._mountedElements.set(index, option);
835
- console.log(`[OptionRenderer] Rendered lightweight option ${index}: ${label}`);
836
830
  return option;
837
831
  }
838
832
  /**
@@ -892,7 +886,6 @@ class OptionRenderer {
892
886
  }
893
887
  });
894
888
  }
895
- console.log(`[OptionRenderer] Rendered custom component option ${index}: ${label}`);
896
889
  }
897
890
  catch (error) {
898
891
  console.error(`[OptionRenderer] Failed to render custom component at index ${index}:`, error);
@@ -1490,13 +1483,10 @@ class EnhancedSelect extends HTMLElement {
1490
1483
  this._hasError = false;
1491
1484
  this._errorMessage = '';
1492
1485
  this._boundArrowClick = null;
1493
- console.log('[EnhancedSelect] Constructor called');
1494
1486
  this._shadow = this.attachShadow({ mode: 'open' });
1495
- console.log('[EnhancedSelect] Shadow root attached:', this._shadow);
1496
1487
  this._uniqueId = `enhanced-select-${Math.random().toString(36).substr(2, 9)}`;
1497
1488
  // Merge global config with component-level config
1498
1489
  this._config = selectConfig.getConfig();
1499
- console.log('[EnhancedSelect] Config loaded');
1500
1490
  // Initialize state
1501
1491
  this._state = {
1502
1492
  isOpen: false,
@@ -1516,41 +1506,26 @@ class EnhancedSelect extends HTMLElement {
1516
1506
  lastNotifiedResultCount: 0,
1517
1507
  isExpanded: false,
1518
1508
  };
1519
- console.log('[EnhancedSelect] State initialized');
1520
1509
  // Create DOM structure
1521
1510
  this._container = this._createContainer();
1522
- console.log('[EnhancedSelect] Container created:', this._container);
1523
1511
  this._inputContainer = this._createInputContainer();
1524
- console.log('[EnhancedSelect] Input container created');
1525
1512
  this._input = this._createInput();
1526
- console.log('[EnhancedSelect] Input created:', this._input);
1527
1513
  this._arrowContainer = this._createArrowContainer();
1528
- console.log('[EnhancedSelect] Arrow container created');
1529
1514
  this._dropdown = this._createDropdown();
1530
- console.log('[EnhancedSelect] Dropdown created');
1531
1515
  this._optionsContainer = this._createOptionsContainer();
1532
- console.log('[EnhancedSelect] Options container created');
1533
1516
  this._liveRegion = this._createLiveRegion();
1534
- console.log('[EnhancedSelect] Live region created');
1535
1517
  // Initialize styles BEFORE assembling DOM (order matters in shadow DOM)
1536
1518
  this._initializeStyles();
1537
- console.log('[EnhancedSelect] Styles initialized');
1538
1519
  this._assembleDOM();
1539
- console.log('[EnhancedSelect] DOM assembled');
1540
1520
  this._attachEventListeners();
1541
- console.log('[EnhancedSelect] Event listeners attached');
1542
1521
  this._initializeObservers();
1543
- console.log('[EnhancedSelect] Observers initialized');
1544
- console.log('[EnhancedSelect] Constructor complete, shadow DOM children:', this._shadow.children.length);
1545
1522
  }
1546
1523
  connectedCallback() {
1547
- console.log('[EnhancedSelect] connectedCallback called');
1548
1524
  // WORKAROUND: Force display style on host element for Angular compatibility
1549
1525
  // Angular's rendering seems to not apply :host styles correctly in some cases
1550
1526
  // Must be done in connectedCallback when element is attached to DOM
1551
1527
  this.style.display = 'block';
1552
1528
  this.style.width = '100%';
1553
- console.log('[EnhancedSelect] Forced host display styles');
1554
1529
  // Load initial data if server-side is enabled
1555
1530
  if (this._config.serverSide.enabled && this._config.serverSide.initialSelectedValues) {
1556
1531
  this._loadInitialSelectedItems();
@@ -1559,7 +1534,6 @@ class EnhancedSelect extends HTMLElement {
1559
1534
  if (this._config.callbacks.onOpen) {
1560
1535
  this._config.callbacks.onOpen();
1561
1536
  }
1562
- console.log('[EnhancedSelect] connectedCallback complete');
1563
1537
  }
1564
1538
  disconnectedCallback() {
1565
1539
  // Cleanup observers
@@ -1657,43 +1631,22 @@ class EnhancedSelect extends HTMLElement {
1657
1631
  return container;
1658
1632
  }
1659
1633
  _assembleDOM() {
1660
- console.log('[EnhancedSelect] _assembleDOM: Starting DOM assembly');
1661
- console.log('[EnhancedSelect] _assembleDOM: Elements to assemble:', {
1662
- inputContainer: !!this._inputContainer,
1663
- input: !!this._input,
1664
- arrowContainer: !!this._arrowContainer,
1665
- container: !!this._container,
1666
- dropdown: !!this._dropdown,
1667
- optionsContainer: !!this._optionsContainer,
1668
- shadow: !!this._shadow,
1669
- liveRegion: !!this._liveRegion
1670
- });
1671
1634
  this._inputContainer.appendChild(this._input);
1672
- console.log('[EnhancedSelect] _assembleDOM: Appended input to inputContainer');
1673
1635
  if (this._arrowContainer) {
1674
1636
  this._inputContainer.appendChild(this._arrowContainer);
1675
- console.log('[EnhancedSelect] _assembleDOM: Appended arrowContainer to inputContainer');
1676
1637
  }
1677
1638
  this._container.appendChild(this._inputContainer);
1678
- console.log('[EnhancedSelect] _assembleDOM: Appended inputContainer to container');
1679
1639
  this._dropdown.appendChild(this._optionsContainer);
1680
- console.log('[EnhancedSelect] _assembleDOM: Appended optionsContainer to dropdown');
1681
1640
  this._container.appendChild(this._dropdown);
1682
- console.log('[EnhancedSelect] _assembleDOM: Appended dropdown to container');
1683
1641
  this._shadow.appendChild(this._container);
1684
- console.log('[EnhancedSelect] _assembleDOM: Appended container to shadow root');
1685
1642
  if (this._liveRegion) {
1686
1643
  this._shadow.appendChild(this._liveRegion);
1687
- console.log('[EnhancedSelect] _assembleDOM: Appended liveRegion to shadow root');
1688
1644
  }
1689
- console.log('[EnhancedSelect] _assembleDOM: Shadow root children count:', this._shadow.children.length);
1690
- console.log('[EnhancedSelect] _assembleDOM: Shadow root HTML length:', this._shadow.innerHTML.length);
1691
1645
  // Set ARIA relationships
1692
1646
  const listboxId = `${this._uniqueId}-listbox`;
1693
1647
  this._dropdown.id = listboxId;
1694
1648
  this._input.setAttribute('aria-controls', listboxId);
1695
1649
  this._input.setAttribute('aria-owns', listboxId);
1696
- console.log('[EnhancedSelect] _assembleDOM: Set ARIA relationships with listboxId:', listboxId);
1697
1650
  }
1698
1651
  _initializeStyles() {
1699
1652
  const style = document.createElement('style');
@@ -1863,28 +1816,32 @@ class EnhancedSelect extends HTMLElement {
1863
1816
  max-height: 300px;
1864
1817
  overflow: auto;
1865
1818
  transition: opacity 0.2s ease-in-out;
1819
+ background: var(--select-options-bg, white);
1866
1820
  }
1867
1821
 
1868
1822
  .option {
1869
- padding: 8px 12px;
1823
+ padding: var(--select-option-padding, 8px 12px);
1870
1824
  cursor: pointer;
1871
- color: inherit;
1825
+ color: var(--select-option-color, #1f2937);
1826
+ background: var(--select-option-bg, white);
1872
1827
  transition: background-color 0.15s ease;
1873
1828
  user-select: none;
1874
1829
  }
1875
1830
 
1876
1831
  .option:hover {
1877
- background-color: #f3f4f6;
1832
+ background-color: var(--select-option-hover-bg, #f3f4f6);
1833
+ color: var(--select-option-hover-color, #1f2937);
1878
1834
  }
1879
1835
 
1880
1836
  .option.selected {
1881
- background-color: #e0e7ff;
1882
- color: #4338ca;
1837
+ background-color: var(--select-option-selected-bg, #e0e7ff);
1838
+ color: var(--select-option-selected-color, #4338ca);
1883
1839
  font-weight: 500;
1884
1840
  }
1885
1841
 
1886
1842
  .option.active {
1887
- background-color: #f3f4f6;
1843
+ background-color: var(--select-option-active-bg, #f3f4f6);
1844
+ color: var(--select-option-active-color, #1f2937);
1888
1845
  }
1889
1846
 
1890
1847
  .load-more-container {
@@ -1973,22 +1930,39 @@ class EnhancedSelect extends HTMLElement {
1973
1930
  }
1974
1931
  }
1975
1932
 
1976
- /* Accessibility: Dark mode */
1977
- @media (prefers-color-scheme: dark) {
1978
- .select-input {
1933
+ /* Dark mode - Opt-in via class or data attribute */
1934
+ :host(.dark-mode),
1935
+ :host([data-theme="dark"]) {
1936
+ .input-container {
1979
1937
  background: var(--select-dark-bg, #1f2937);
1980
- color: var(--select-dark-text, #f9fafb);
1981
1938
  border-color: var(--select-dark-border, #4b5563);
1982
1939
  }
1983
1940
 
1941
+ .select-input {
1942
+ color: var(--select-dark-text, #f9fafb);
1943
+ }
1944
+
1945
+ .select-input::placeholder {
1946
+ color: var(--select-dark-placeholder, #6b7280);
1947
+ }
1948
+
1984
1949
  .select-dropdown {
1985
1950
  background: var(--select-dark-dropdown-bg, #1f2937);
1986
1951
  border-color: var(--select-dark-dropdown-border, #4b5563);
1987
- color: var(--select-dark-text, #f9fafb);
1952
+ }
1953
+
1954
+ .options-container {
1955
+ background: var(--select-dark-options-bg, #1f2937);
1956
+ }
1957
+
1958
+ .option {
1959
+ color: var(--select-dark-option-color, #f9fafb);
1960
+ background: var(--select-dark-option-bg, #1f2937);
1988
1961
  }
1989
1962
 
1990
1963
  .option:hover {
1991
1964
  background-color: var(--select-dark-option-hover-bg, #374151);
1965
+ color: var(--select-dark-option-hover-color, #f9fafb);
1992
1966
  }
1993
1967
 
1994
1968
  .option.selected {
@@ -1998,11 +1972,23 @@ class EnhancedSelect extends HTMLElement {
1998
1972
 
1999
1973
  .option.active {
2000
1974
  background-color: var(--select-dark-option-active-bg, #374151);
1975
+ color: var(--select-dark-option-active-color, #f9fafb);
2001
1976
  }
2002
1977
 
2003
- .busy-bucket {
1978
+ .busy-bucket,
1979
+ .empty-state {
2004
1980
  color: var(--select-dark-busy-color, #9ca3af);
2005
1981
  }
1982
+
1983
+ .input-container::after {
1984
+ background: linear-gradient(
1985
+ to bottom,
1986
+ transparent 0%,
1987
+ rgba(255, 255, 255, 0.1) 20%,
1988
+ rgba(255, 255, 255, 0.1) 80%,
1989
+ transparent 100%
1990
+ );
1991
+ }
2006
1992
  }
2007
1993
 
2008
1994
  /* Accessibility: High contrast mode */
@@ -2023,8 +2009,6 @@ class EnhancedSelect extends HTMLElement {
2023
2009
  min-height: 44px;
2024
2010
  }
2025
2011
  `;
2026
- console.log('[EnhancedSelect] _initializeStyles: Created style element, content length:', style.textContent?.length || 0);
2027
- console.log('[EnhancedSelect] _initializeStyles: Shadow root children BEFORE:', this._shadow.children.length);
2028
2012
  // Insert as first child to ensure styles are processed first
2029
2013
  if (this._shadow.firstChild) {
2030
2014
  this._shadow.insertBefore(style, this._shadow.firstChild);
@@ -2032,9 +2016,6 @@ class EnhancedSelect extends HTMLElement {
2032
2016
  else {
2033
2017
  this._shadow.appendChild(style);
2034
2018
  }
2035
- console.log('[EnhancedSelect] _initializeStyles: Style inserted, shadow root children AFTER:', this._shadow.children.length);
2036
- console.log('[EnhancedSelect] _initializeStyles: Shadow root has style element:', !!this._shadow.querySelector('style'));
2037
- console.log('[EnhancedSelect] _initializeStyles: Style sheet rules:', style.sheet?.cssRules?.length || 'NOT PARSED');
2038
2019
  }
2039
2020
  _attachEventListeners() {
2040
2021
  // Arrow click handler
@@ -2641,27 +2622,21 @@ class EnhancedSelect extends HTMLElement {
2641
2622
  * Set items to display in the select
2642
2623
  */
2643
2624
  setItems(items) {
2644
- console.log('[EnhancedSelect] setItems called with', items?.length || 0, 'items');
2645
- console.log('[EnhancedSelect] Items:', items);
2646
2625
  const previousLength = this._state.loadedItems.length;
2647
2626
  this._state.loadedItems = items;
2648
2627
  // If grouped items exist, flatten them to items
2649
2628
  if (this._state.groupedItems.length > 0) {
2650
2629
  this._state.loadedItems = this._state.groupedItems.flatMap(group => group.options);
2651
- console.log('[EnhancedSelect] Flattened grouped items to', this._state.loadedItems.length, 'items');
2652
2630
  }
2653
2631
  const newLength = this._state.loadedItems.length;
2654
- console.log('[EnhancedSelect] State.loadedItems updated:', previousLength, '→', newLength);
2655
2632
  // When infinite scroll is active (preserveScrollPosition = true),
2656
2633
  // we need to maintain scroll position during the update
2657
2634
  if (this._state.preserveScrollPosition && this._dropdown) {
2658
2635
  const targetScrollTop = this._state.lastScrollPosition;
2659
- console.log('[EnhancedSelect] Preserving scroll position:', targetScrollTop);
2660
2636
  // Only clear loading if we actually got more items
2661
2637
  if (newLength > previousLength) {
2662
2638
  this._state.isBusy = false;
2663
2639
  }
2664
- console.log('[EnhancedSelect] Calling _renderOptions (with scroll preservation)...');
2665
2640
  this._renderOptions();
2666
2641
  // Restore the exact scrollTop we had before loading
2667
2642
  // so the previously visible items stay in place and
@@ -2681,10 +2656,8 @@ class EnhancedSelect extends HTMLElement {
2681
2656
  else {
2682
2657
  // Normal update - just render normally
2683
2658
  this._state.isBusy = false;
2684
- console.log('[EnhancedSelect] Calling _renderOptions (normal)...');
2685
2659
  this._renderOptions();
2686
2660
  }
2687
- console.log('[EnhancedSelect] setItems complete');
2688
2661
  }
2689
2662
  /**
2690
2663
  * Set grouped items
@@ -2848,21 +2821,11 @@ class EnhancedSelect extends HTMLElement {
2848
2821
  * Render options based on current state
2849
2822
  */
2850
2823
  _renderOptions() {
2851
- console.log('[EnhancedSelect] _renderOptions called');
2852
- console.log('[EnhancedSelect] State:', {
2853
- loadedItems: this._state.loadedItems.length,
2854
- groupedItems: this._state.groupedItems.length,
2855
- isOpen: this._state.isOpen,
2856
- isSearching: this._state.isSearching,
2857
- searchQuery: this._state.searchQuery,
2858
- isBusy: this._state.isBusy
2859
- });
2860
2824
  // Cleanup observer
2861
2825
  if (this._loadMoreTrigger && this._intersectionObserver) {
2862
2826
  this._intersectionObserver.unobserve(this._loadMoreTrigger);
2863
2827
  }
2864
2828
  // Clear options container
2865
- console.log('[EnhancedSelect] Clearing options container, previous children:', this._optionsContainer.children.length);
2866
2829
  this._optionsContainer.innerHTML = '';
2867
2830
  // Ensure dropdown only contains options container (cleanup legacy direct children)
2868
2831
  // We need to preserve optionsContainer, so we can't just clear dropdown.innerHTML
@@ -2875,7 +2838,6 @@ class EnhancedSelect extends HTMLElement {
2875
2838
  // Ensure dropdown is visible if we are rendering options
2876
2839
  if (this._state.isOpen && this._dropdown.style.display === 'none') {
2877
2840
  this._dropdown.style.display = 'block';
2878
- console.log('[EnhancedSelect] Dropdown display set to block');
2879
2841
  }
2880
2842
  // Show searching state (exclusive state)
2881
2843
  if (this._state.isSearching) {
@@ -2883,7 +2845,6 @@ class EnhancedSelect extends HTMLElement {
2883
2845
  searching.className = 'searching-state';
2884
2846
  searching.textContent = 'Searching...';
2885
2847
  this._optionsContainer.appendChild(searching);
2886
- console.log('[EnhancedSelect] Added searching state');
2887
2848
  return;
2888
2849
  }
2889
2850
  const getValue = this._config.serverSide.getValueFromItem || ((item) => item?.value ?? item);
@@ -2892,7 +2853,6 @@ class EnhancedSelect extends HTMLElement {
2892
2853
  const query = this._state.searchQuery.toLowerCase();
2893
2854
  // Handle Grouped Items Rendering (when no search query)
2894
2855
  if (this._state.groupedItems.length > 0 && !query) {
2895
- console.log('[EnhancedSelect] Rendering grouped items:', this._state.groupedItems.length, 'groups');
2896
2856
  this._state.groupedItems.forEach(group => {
2897
2857
  const header = document.createElement('div');
2898
2858
  header.className = 'group-header';
@@ -2922,7 +2882,6 @@ class EnhancedSelect extends HTMLElement {
2922
2882
  }
2923
2883
  else {
2924
2884
  // Normal rendering (flat list or filtered)
2925
- console.log('[EnhancedSelect] Rendering flat list:', this._state.loadedItems.length, 'items');
2926
2885
  let hasRenderedItems = false;
2927
2886
  this._state.loadedItems.forEach((item, index) => {
2928
2887
  // Apply filter if query exists
@@ -2939,7 +2898,6 @@ class EnhancedSelect extends HTMLElement {
2939
2898
  hasRenderedItems = true;
2940
2899
  this._renderSingleOption(item, index, getValue, getLabel);
2941
2900
  });
2942
- console.log('[EnhancedSelect] Rendered', hasRenderedItems ? 'items' : 'no items');
2943
2901
  if (!hasRenderedItems && !this._state.isBusy) {
2944
2902
  const empty = document.createElement('div');
2945
2903
  empty.className = 'empty-state';
@@ -2950,7 +2908,6 @@ class EnhancedSelect extends HTMLElement {
2950
2908
  empty.textContent = 'No options available';
2951
2909
  }
2952
2910
  this._optionsContainer.appendChild(empty);
2953
- console.log('[EnhancedSelect] Added empty state');
2954
2911
  }
2955
2912
  }
2956
2913
  // Append Busy Indicator if busy
@@ -2968,13 +2925,11 @@ class EnhancedSelect extends HTMLElement {
2968
2925
  busyBucket.appendChild(message);
2969
2926
  }
2970
2927
  this._optionsContainer.appendChild(busyBucket);
2971
- console.log('[EnhancedSelect] Added busy bucket');
2972
2928
  }
2973
2929
  // Append Load More Trigger (Button or Sentinel) if enabled and not busy
2974
2930
  else if ((this._config.loadMore.enabled || this._config.infiniteScroll.enabled) && this._state.loadedItems.length > 0) {
2975
2931
  this._addLoadMoreTrigger();
2976
2932
  }
2977
- console.log('[EnhancedSelect] _renderOptions complete, optionsContainer children:', this._optionsContainer.children.length);
2978
2933
  }
2979
2934
  _renderSingleOption(item, index, getValue, getLabel) {
2980
2935
  const option = document.createElement('div');
@@ -2982,7 +2937,6 @@ class EnhancedSelect extends HTMLElement {
2982
2937
  option.id = `${this._uniqueId}-option-${index}`;
2983
2938
  const value = getValue(item);
2984
2939
  const label = getLabel(item);
2985
- console.log('[EnhancedSelect] Rendering option', index, ':', { value, label });
2986
2940
  option.textContent = label;
2987
2941
  option.dataset.value = String(value);
2988
2942
  option.dataset.index = String(index); // Also useful for debugging/selectors
@@ -2999,7 +2953,6 @@ class EnhancedSelect extends HTMLElement {
2999
2953
  this._selectOption(index);
3000
2954
  });
3001
2955
  this._optionsContainer.appendChild(option);
3002
- console.log('[EnhancedSelect] Option', index, 'appended to optionsContainer');
3003
2956
  }
3004
2957
  _addLoadMoreTrigger() {
3005
2958
  const container = document.createElement('div');
@@ -3832,7 +3785,6 @@ async function measureAsync(label, fn) {
3832
3785
  const start = performance.now();
3833
3786
  const result = await fn();
3834
3787
  const duration = performance.now() - start;
3835
- console.log(`[Perf] ${label}: ${duration.toFixed(2)}ms`);
3836
3788
  return { result, duration };
3837
3789
  }
3838
3790
  /**
@@ -3842,7 +3794,6 @@ function measureSync(label, fn) {
3842
3794
  const start = performance.now();
3843
3795
  const result = fn();
3844
3796
  const duration = performance.now() - start;
3845
- console.log(`[Perf] ${label}: ${duration.toFixed(2)}ms`);
3846
3797
  return { result, duration };
3847
3798
  }
3848
3799