@smilodon/core 1.4.0 → 1.4.2

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
@@ -1828,6 +1828,10 @@ class EnhancedSelect extends HTMLElement {
1828
1828
  this._pendingFirstRenderMark = false;
1829
1829
  this._pendingSearchRenderMark = false;
1830
1830
  this._rangeAnchorIndex = null;
1831
+ this._customOptionBoundElements = new WeakSet();
1832
+ this._mirrorGlobalStylesForCustomOptions = false;
1833
+ this._globalStylesObserver = null;
1834
+ this._globalStylesContainer = null;
1831
1835
  this._shadow = this.attachShadow({ mode: 'open' });
1832
1836
  this._uniqueId = `enhanced-select-${Math.random().toString(36).substr(2, 9)}`;
1833
1837
  this._rendererHelpers = this._buildRendererHelpers();
@@ -1872,6 +1876,9 @@ class EnhancedSelect extends HTMLElement {
1872
1876
  // Must be done in connectedCallback when element is attached to DOM
1873
1877
  this.style.display = 'block';
1874
1878
  this.style.width = '100%';
1879
+ if (this._optionRenderer) {
1880
+ this._setGlobalStylesMirroring(true);
1881
+ }
1875
1882
  // Load initial data if server-side is enabled
1876
1883
  if (this._config.serverSide.enabled && this._config.serverSide.initialSelectedValues) {
1877
1884
  this._loadInitialSelectedItems();
@@ -1895,6 +1902,92 @@ class EnhancedSelect extends HTMLElement {
1895
1902
  if (this._boundArrowClick && this._arrowContainer) {
1896
1903
  this._arrowContainer.removeEventListener('click', this._boundArrowClick);
1897
1904
  }
1905
+ this._teardownGlobalStylesMirroring();
1906
+ }
1907
+ _setGlobalStylesMirroring(enabled) {
1908
+ if (this._mirrorGlobalStylesForCustomOptions === enabled) {
1909
+ if (enabled) {
1910
+ this._mirrorDocumentStylesIntoShadow();
1911
+ }
1912
+ return;
1913
+ }
1914
+ this._mirrorGlobalStylesForCustomOptions = enabled;
1915
+ if (enabled) {
1916
+ this._setupGlobalStylesMirroring();
1917
+ }
1918
+ else {
1919
+ this._teardownGlobalStylesMirroring();
1920
+ }
1921
+ }
1922
+ _setupGlobalStylesMirroring() {
1923
+ if (typeof document === 'undefined')
1924
+ return;
1925
+ if (!this._mirrorGlobalStylesForCustomOptions)
1926
+ return;
1927
+ this._mirrorDocumentStylesIntoShadow();
1928
+ if (this._globalStylesObserver)
1929
+ return;
1930
+ this._globalStylesObserver = new MutationObserver(() => {
1931
+ this._mirrorDocumentStylesIntoShadow();
1932
+ });
1933
+ this._globalStylesObserver.observe(document.head, {
1934
+ childList: true,
1935
+ subtree: true,
1936
+ attributes: true,
1937
+ characterData: true,
1938
+ });
1939
+ }
1940
+ _teardownGlobalStylesMirroring() {
1941
+ if (this._globalStylesObserver) {
1942
+ this._globalStylesObserver.disconnect();
1943
+ this._globalStylesObserver = null;
1944
+ }
1945
+ if (this._globalStylesContainer) {
1946
+ this._globalStylesContainer.remove();
1947
+ this._globalStylesContainer = null;
1948
+ }
1949
+ }
1950
+ _mirrorDocumentStylesIntoShadow() {
1951
+ if (typeof document === 'undefined')
1952
+ return;
1953
+ if (!this._mirrorGlobalStylesForCustomOptions)
1954
+ return;
1955
+ if (!this._globalStylesContainer) {
1956
+ this._globalStylesContainer = document.createElement('div');
1957
+ this._globalStylesContainer.setAttribute('data-smilodon-global-styles', '');
1958
+ this._shadow.appendChild(this._globalStylesContainer);
1959
+ }
1960
+ const container = this._globalStylesContainer;
1961
+ container.innerHTML = '';
1962
+ const styleNodes = Array.from(document.querySelectorAll('style,link[rel="stylesheet"]'));
1963
+ styleNodes.forEach((node, index) => {
1964
+ if (node instanceof HTMLStyleElement) {
1965
+ const clonedStyle = document.createElement('style');
1966
+ clonedStyle.setAttribute('data-smilodon-global-style', String(index));
1967
+ clonedStyle.textContent = node.textContent || '';
1968
+ container.appendChild(clonedStyle);
1969
+ return;
1970
+ }
1971
+ if (node instanceof HTMLLinkElement && node.href) {
1972
+ const clonedLink = document.createElement('link');
1973
+ clonedLink.rel = 'stylesheet';
1974
+ clonedLink.href = node.href;
1975
+ if (node.media)
1976
+ clonedLink.media = node.media;
1977
+ if (node.crossOrigin)
1978
+ clonedLink.crossOrigin = node.crossOrigin;
1979
+ if (node.referrerPolicy)
1980
+ clonedLink.referrerPolicy = node.referrerPolicy;
1981
+ if (node.integrity)
1982
+ clonedLink.integrity = node.integrity;
1983
+ if (node.type)
1984
+ clonedLink.type = node.type;
1985
+ if (node.nonce)
1986
+ clonedLink.nonce = node.nonce;
1987
+ clonedLink.setAttribute('data-smilodon-global-link', String(index));
1988
+ container.appendChild(clonedLink);
1989
+ }
1990
+ });
1898
1991
  }
1899
1992
  _createContainer() {
1900
1993
  const container = document.createElement('div');
@@ -2025,15 +2118,15 @@ class EnhancedSelect extends HTMLElement {
2025
2118
  max-height: var(--select-input-max-height, 160px);
2026
2119
  overflow-y: var(--select-input-overflow-y, auto);
2027
2120
  align-content: flex-start;
2028
- background: var(--select-input-bg, white);
2029
- border: var(--select-input-border, 1px solid #d1d5db);
2121
+ background: var(--select-input-bg, var(--select-bg, white));
2122
+ border: var(--select-input-border, 1px solid var(--select-border-color, #d1d5db));
2030
2123
  border-radius: var(--select-input-border-radius, 6px);
2031
2124
  box-sizing: border-box;
2032
2125
  transition: all 0.2s ease;
2033
2126
  }
2034
2127
 
2035
2128
  .input-container:focus-within {
2036
- border-color: var(--select-input-focus-border, #667eea);
2129
+ border-color: var(--select-input-focus-border, var(--select-border-focus-color, #667eea));
2037
2130
  box-shadow: var(--select-input-focus-shadow, 0 0 0 3px rgba(102, 126, 234, 0.1));
2038
2131
  }
2039
2132
 
@@ -2103,7 +2196,7 @@ class EnhancedSelect extends HTMLElement {
2103
2196
  border: none;
2104
2197
  font-size: var(--select-input-font-size, 14px);
2105
2198
  line-height: var(--select-input-line-height, 1.5);
2106
- color: var(--select-input-color, #1f2937);
2199
+ color: var(--select-input-color, var(--select-text-color, #1f2937));
2107
2200
  background: transparent;
2108
2201
  box-sizing: border-box;
2109
2202
  outline: none;
@@ -2111,7 +2204,7 @@ class EnhancedSelect extends HTMLElement {
2111
2204
  }
2112
2205
 
2113
2206
  .select-input::placeholder {
2114
- color: var(--select-input-placeholder-color, #9ca3af);
2207
+ color: var(--select-input-placeholder-color, var(--select-placeholder-color, #9ca3af));
2115
2208
  }
2116
2209
 
2117
2210
  .selection-badge {
@@ -2172,8 +2265,8 @@ class EnhancedSelect extends HTMLElement {
2172
2265
  margin-top: var(--select-dropdown-margin-top, 4px);
2173
2266
  max-height: var(--select-dropdown-max-height, 300px);
2174
2267
  overflow: hidden;
2175
- background: var(--select-dropdown-bg, white);
2176
- border: var(--select-dropdown-border, 1px solid #ccc);
2268
+ background: var(--select-dropdown-bg, var(--select-bg, white));
2269
+ border: 1px solid var(--select-dropdown-border, #ccc);
2177
2270
  border-radius: var(--select-dropdown-border-radius, 4px);
2178
2271
  box-shadow: var(--select-dropdown-shadow, 0 4px 6px rgba(0,0,0,0.1));
2179
2272
  z-index: var(--select-dropdown-z-index, 1000);
@@ -2184,14 +2277,14 @@ class EnhancedSelect extends HTMLElement {
2184
2277
  max-height: var(--select-options-max-height, 300px);
2185
2278
  overflow: auto;
2186
2279
  transition: opacity 0.2s ease-in-out;
2187
- background: var(--select-options-bg, white);
2280
+ background: var(--select-options-bg, var(--select-dropdown-bg, var(--select-bg, white)));
2188
2281
  }
2189
2282
 
2190
2283
  .option {
2191
2284
  padding: var(--select-option-padding, 8px 12px);
2192
2285
  cursor: pointer;
2193
- color: var(--select-option-color, #1f2937);
2194
- background: var(--select-option-bg, white);
2286
+ color: var(--select-option-color, var(--select-text-color, #1f2937));
2287
+ background: var(--select-option-bg, var(--select-dropdown-bg, var(--select-bg, white)));
2195
2288
  transition: var(--select-option-transition, background-color 0.15s ease);
2196
2289
  user-select: none;
2197
2290
  font-size: var(--select-option-font-size, 14px);
@@ -3220,6 +3313,7 @@ class EnhancedSelect extends HTMLElement {
3220
3313
  }
3221
3314
  set optionRenderer(renderer) {
3222
3315
  this._optionRenderer = renderer;
3316
+ this._setGlobalStylesMirroring(Boolean(renderer));
3223
3317
  this._renderOptions();
3224
3318
  }
3225
3319
  /**
@@ -3694,24 +3788,37 @@ class EnhancedSelect extends HTMLElement {
3694
3788
  if (!optionEl.hasAttribute('tabindex')) {
3695
3789
  optionEl.tabIndex = -1;
3696
3790
  }
3697
- if (!meta.disabled) {
3791
+ if (!this._customOptionBoundElements.has(optionEl)) {
3698
3792
  optionEl.addEventListener('click', (e) => {
3699
- e.stopPropagation(); // Prevent duplicate handling by delegation
3793
+ e.stopPropagation();
3794
+ const current = e.currentTarget;
3795
+ if (current.getAttribute('aria-disabled') === 'true')
3796
+ return;
3797
+ const parsedIndex = Number(current.dataset.index);
3798
+ if (!Number.isFinite(parsedIndex))
3799
+ return;
3700
3800
  const mouseEvent = e;
3701
- this._selectOption(meta.index, {
3801
+ this._selectOption(parsedIndex, {
3702
3802
  shiftKey: mouseEvent.shiftKey,
3703
3803
  toggleKey: mouseEvent.ctrlKey || mouseEvent.metaKey,
3704
3804
  });
3705
3805
  });
3706
3806
  optionEl.addEventListener('keydown', (e) => {
3707
- if (e.key === 'Enter' || e.key === ' ') {
3708
- e.preventDefault();
3709
- this._selectOption(meta.index, {
3710
- shiftKey: e.shiftKey,
3711
- toggleKey: e.ctrlKey || e.metaKey,
3712
- });
3713
- }
3807
+ if (e.key !== 'Enter' && e.key !== ' ')
3808
+ return;
3809
+ const current = e.currentTarget;
3810
+ if (current.getAttribute('aria-disabled') === 'true')
3811
+ return;
3812
+ const parsedIndex = Number(current.dataset.index);
3813
+ if (!Number.isFinite(parsedIndex))
3814
+ return;
3815
+ e.preventDefault();
3816
+ this._selectOption(parsedIndex, {
3817
+ shiftKey: e.shiftKey,
3818
+ toggleKey: e.ctrlKey || e.metaKey,
3819
+ });
3714
3820
  });
3821
+ this._customOptionBoundElements.add(optionEl);
3715
3822
  }
3716
3823
  return optionEl;
3717
3824
  }