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