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