@smilodon/core 1.4.10 → 1.4.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/README.md +28 -0
- package/dist/index.cjs +260 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +260 -27
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/index.umd.js +260 -27
- package/dist/index.umd.js.map +1 -1
- package/dist/index.umd.min.js +1 -1
- package/dist/index.umd.min.js.map +1 -1
- package/dist/types/src/components/enhanced-select.d.ts +11 -1
- package/dist/types/src/config/global-config.d.ts +25 -0
- package/dist/types/src/types.d.ts +58 -0
- package/dist/types/tests/capabilities-tracking.spec.d.ts +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1401,6 +1401,18 @@ const defaultConfig = {
|
|
|
1401
1401
|
icon: '×',
|
|
1402
1402
|
},
|
|
1403
1403
|
callbacks: {},
|
|
1404
|
+
tracking: {
|
|
1405
|
+
enabled: false,
|
|
1406
|
+
events: true,
|
|
1407
|
+
styling: true,
|
|
1408
|
+
limitations: true,
|
|
1409
|
+
emitDiagnostics: false,
|
|
1410
|
+
maxEntries: 200,
|
|
1411
|
+
},
|
|
1412
|
+
limitations: {
|
|
1413
|
+
policies: {},
|
|
1414
|
+
autoMitigateRuntimeModeSwitch: true,
|
|
1415
|
+
},
|
|
1404
1416
|
enabled: true,
|
|
1405
1417
|
searchable: false,
|
|
1406
1418
|
placeholder: 'Select an option...',
|
|
@@ -1532,6 +1544,8 @@ class SelectOption extends HTMLElement {
|
|
|
1532
1544
|
padding: var(--select-option-padding, 8px 12px);
|
|
1533
1545
|
cursor: pointer;
|
|
1534
1546
|
user-select: none;
|
|
1547
|
+
color: var(--select-option-color, var(--select-text-color, #1f2937));
|
|
1548
|
+
background: var(--select-option-bg, var(--select-dropdown-bg, var(--select-bg, white)));
|
|
1535
1549
|
transition: var(--select-option-transition, background-color 0.2s ease);
|
|
1536
1550
|
border: var(--select-option-border, none);
|
|
1537
1551
|
border-bottom: var(--select-option-border-bottom, none);
|
|
@@ -1576,9 +1590,20 @@ class SelectOption extends HTMLElement {
|
|
|
1576
1590
|
|
|
1577
1591
|
.option-content {
|
|
1578
1592
|
flex: 1;
|
|
1579
|
-
overflow: hidden;
|
|
1580
|
-
text-overflow: ellipsis;
|
|
1581
|
-
white-space: nowrap;
|
|
1593
|
+
overflow: var(--select-option-content-overflow, hidden);
|
|
1594
|
+
text-overflow: var(--select-option-content-text-overflow, ellipsis);
|
|
1595
|
+
white-space: var(--select-option-content-white-space, nowrap);
|
|
1596
|
+
}
|
|
1597
|
+
|
|
1598
|
+
.checkmark-icon {
|
|
1599
|
+
display: none;
|
|
1600
|
+
margin-left: var(--select-checkmark-margin-left, 8px);
|
|
1601
|
+
color: var(--select-checkmark-color, currentColor);
|
|
1602
|
+
}
|
|
1603
|
+
|
|
1604
|
+
:host([aria-selected="true"]) .checkmark-icon,
|
|
1605
|
+
.option-container.selected .checkmark-icon {
|
|
1606
|
+
display: inline-flex;
|
|
1582
1607
|
}
|
|
1583
1608
|
|
|
1584
1609
|
.remove-button {
|
|
@@ -1706,16 +1731,6 @@ class SelectOption extends HTMLElement {
|
|
|
1706
1731
|
<path d="M4 8.5L6.5 11L12 5.5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
1707
1732
|
</svg>
|
|
1708
1733
|
`;
|
|
1709
|
-
// Visibility control via CSS or inline style
|
|
1710
|
-
// We set it to display: none unless selected.
|
|
1711
|
-
// User can override this behavior via part styling if they want transitions
|
|
1712
|
-
if (!selected) {
|
|
1713
|
-
checkmark.style.display = 'none';
|
|
1714
|
-
}
|
|
1715
|
-
else {
|
|
1716
|
-
checkmark.style.marginLeft = '8px';
|
|
1717
|
-
checkmark.style.color = 'currentColor';
|
|
1718
|
-
}
|
|
1719
1734
|
this._container.appendChild(checkmark);
|
|
1720
1735
|
}
|
|
1721
1736
|
// Data Attributes Contract on Host
|
|
@@ -1874,6 +1889,10 @@ class EnhancedSelect extends HTMLElement {
|
|
|
1874
1889
|
set classMap(map) {
|
|
1875
1890
|
this._classMap = map;
|
|
1876
1891
|
this._setGlobalStylesMirroring(Boolean(this._optionRenderer || map || this._groupHeaderRenderer));
|
|
1892
|
+
this._track('style', 'classMapChanged', {
|
|
1893
|
+
hasClassMap: Boolean(map),
|
|
1894
|
+
keys: map ? Object.keys(map) : [],
|
|
1895
|
+
});
|
|
1877
1896
|
if (!this.isConnected)
|
|
1878
1897
|
return;
|
|
1879
1898
|
this._renderOptions();
|
|
@@ -1889,6 +1908,7 @@ class EnhancedSelect extends HTMLElement {
|
|
|
1889
1908
|
set groupHeaderRenderer(renderer) {
|
|
1890
1909
|
this._groupHeaderRenderer = renderer;
|
|
1891
1910
|
this._setGlobalStylesMirroring(Boolean(this._optionRenderer || this._classMap || renderer));
|
|
1911
|
+
this._track('style', 'groupHeaderRendererChanged', { enabled: Boolean(renderer) });
|
|
1892
1912
|
if (!this.isConnected)
|
|
1893
1913
|
return;
|
|
1894
1914
|
this._renderOptions();
|
|
@@ -1907,6 +1927,7 @@ class EnhancedSelect extends HTMLElement {
|
|
|
1907
1927
|
this._mirrorGlobalStylesForCustomOptions = false;
|
|
1908
1928
|
this._globalStylesObserver = null;
|
|
1909
1929
|
this._globalStylesContainer = null;
|
|
1930
|
+
this._tracking = { events: [], styles: [], limitations: [] };
|
|
1910
1931
|
this._shadow = this.attachShadow({ mode: 'open' });
|
|
1911
1932
|
this._uniqueId = `enhanced-select-${Math.random().toString(36).substr(2, 9)}`;
|
|
1912
1933
|
this._rendererHelpers = this._buildRendererHelpers();
|
|
@@ -1953,7 +1974,6 @@ class EnhancedSelect extends HTMLElement {
|
|
|
1953
1974
|
// Angular's rendering seems to not apply :host styles correctly in some cases
|
|
1954
1975
|
// Must be done in connectedCallback when element is attached to DOM
|
|
1955
1976
|
this.style.display = 'block';
|
|
1956
|
-
this.style.width = '100%';
|
|
1957
1977
|
if (this._optionRenderer) {
|
|
1958
1978
|
this._setGlobalStylesMirroring(true);
|
|
1959
1979
|
}
|
|
@@ -1992,6 +2012,7 @@ class EnhancedSelect extends HTMLElement {
|
|
|
1992
2012
|
return;
|
|
1993
2013
|
}
|
|
1994
2014
|
this._mirrorGlobalStylesForCustomOptions = enabled;
|
|
2015
|
+
this._track('style', 'globalStylesMirroringChanged', { enabled });
|
|
1995
2016
|
if (enabled) {
|
|
1996
2017
|
this._setupGlobalStylesMirroring();
|
|
1997
2018
|
}
|
|
@@ -2196,7 +2217,8 @@ class EnhancedSelect extends HTMLElement {
|
|
|
2196
2217
|
:host {
|
|
2197
2218
|
display: block;
|
|
2198
2219
|
position: relative;
|
|
2199
|
-
width: 100
|
|
2220
|
+
width: var(--select-width, 100%);
|
|
2221
|
+
height: var(--select-height, auto);
|
|
2200
2222
|
}
|
|
2201
2223
|
|
|
2202
2224
|
.select-container {
|
|
@@ -2212,6 +2234,7 @@ class EnhancedSelect extends HTMLElement {
|
|
|
2212
2234
|
flex-wrap: wrap;
|
|
2213
2235
|
gap: var(--select-input-gap, 6px);
|
|
2214
2236
|
padding: var(--select-input-padding, 6px 52px 6px 8px);
|
|
2237
|
+
height: var(--select-input-height, auto);
|
|
2215
2238
|
min-height: var(--select-input-min-height, 44px);
|
|
2216
2239
|
max-height: var(--select-input-max-height, 160px);
|
|
2217
2240
|
overflow-y: var(--select-input-overflow-y, auto);
|
|
@@ -2233,17 +2256,17 @@ class EnhancedSelect extends HTMLElement {
|
|
|
2233
2256
|
content: '';
|
|
2234
2257
|
position: absolute;
|
|
2235
2258
|
top: 50%;
|
|
2236
|
-
right: var(--select-separator-position, 40px);
|
|
2259
|
+
right: var(--select-separator-position, var(--select-seperator-position, 40px));
|
|
2237
2260
|
transform: translateY(-50%);
|
|
2238
|
-
width: var(--select-separator-width, 1px);
|
|
2239
|
-
height: var(--select-separator-height, 60%);
|
|
2240
|
-
background: var(--select-separator-bg, var(--select-separator-gradient, linear-gradient(
|
|
2261
|
+
width: var(--select-separator-width, var(--select-seperator-width, 1px));
|
|
2262
|
+
height: var(--select-separator-height, var(--select-seperator-height, 60%));
|
|
2263
|
+
background: var(--select-separator-bg, var(--select-seperator-bg, var(--select-separator-gradient, var(--select-seperator-gradient, linear-gradient(
|
|
2241
2264
|
to bottom,
|
|
2242
2265
|
transparent 0%,
|
|
2243
2266
|
rgba(0, 0, 0, 0.1) 20%,
|
|
2244
2267
|
rgba(0, 0, 0, 0.1) 80%,
|
|
2245
2268
|
transparent 100%
|
|
2246
|
-
)));
|
|
2269
|
+
))));
|
|
2247
2270
|
pointer-events: none;
|
|
2248
2271
|
z-index: 1;
|
|
2249
2272
|
}
|
|
@@ -2270,7 +2293,7 @@ class EnhancedSelect extends HTMLElement {
|
|
|
2270
2293
|
}
|
|
2271
2294
|
|
|
2272
2295
|
.input-container.has-clear-control::after {
|
|
2273
|
-
right: var(--select-separator-position-with-clear, 72px);
|
|
2296
|
+
right: var(--select-separator-position-with-clear, var(--select-seperator-position-with-clear, 72px));
|
|
2274
2297
|
}
|
|
2275
2298
|
|
|
2276
2299
|
.dropdown-arrow-container.with-clear-control {
|
|
@@ -2348,6 +2371,7 @@ class EnhancedSelect extends HTMLElement {
|
|
|
2348
2371
|
|
|
2349
2372
|
.select-input {
|
|
2350
2373
|
flex: 1;
|
|
2374
|
+
width: var(--select-input-width, auto);
|
|
2351
2375
|
min-width: var(--select-input-min-width, 120px);
|
|
2352
2376
|
padding: var(--select-input-field-padding, 4px);
|
|
2353
2377
|
border: none;
|
|
@@ -2442,6 +2466,7 @@ class EnhancedSelect extends HTMLElement {
|
|
|
2442
2466
|
font-weight: var(--select-group-header-weight, 600);
|
|
2443
2467
|
color: var(--select-group-header-color, #6b7280);
|
|
2444
2468
|
background-color: var(--select-group-header-bg, #f3f4f6);
|
|
2469
|
+
text-align: var(--select-group-header-text-align, left);
|
|
2445
2470
|
font-size: var(--select-group-header-font-size, 12px);
|
|
2446
2471
|
text-transform: var(--select-group-header-text-transform, uppercase);
|
|
2447
2472
|
letter-spacing: var(--select-group-header-letter-spacing, 0.05em);
|
|
@@ -2626,10 +2651,25 @@ class EnhancedSelect extends HTMLElement {
|
|
|
2626
2651
|
|
|
2627
2652
|
/* Dark mode - Opt-in via class, data attribute, or ancestor context */
|
|
2628
2653
|
:host(.dark-mode),
|
|
2654
|
+
:host([dark-mode]),
|
|
2655
|
+
:host([darkmode]),
|
|
2629
2656
|
:host([data-theme="dark"]),
|
|
2657
|
+
:host([theme="dark"]),
|
|
2630
2658
|
:host-context(.dark-mode),
|
|
2631
2659
|
:host-context(.dark),
|
|
2632
|
-
:host-context([
|
|
2660
|
+
:host-context([dark-mode]),
|
|
2661
|
+
:host-context([darkmode]),
|
|
2662
|
+
:host-context([data-theme="dark"]),
|
|
2663
|
+
:host-context([theme="dark"]) {
|
|
2664
|
+
/* map dark tokens to base option tokens so nested <select-option>
|
|
2665
|
+
components also pick up dark mode via inherited CSS variables */
|
|
2666
|
+
--select-option-bg: var(--select-dark-option-bg, #1f2937);
|
|
2667
|
+
--select-option-color: var(--select-dark-option-color, #f9fafb);
|
|
2668
|
+
--select-option-hover-bg: var(--select-dark-option-hover-bg, #374151);
|
|
2669
|
+
--select-option-hover-color: var(--select-dark-option-hover-color, #f9fafb);
|
|
2670
|
+
--select-option-selected-bg: var(--select-dark-option-selected-bg, #3730a3);
|
|
2671
|
+
--select-option-selected-color: var(--select-dark-option-selected-text, #e0e7ff);
|
|
2672
|
+
|
|
2633
2673
|
.input-container {
|
|
2634
2674
|
background: var(--select-dark-bg, #1f2937);
|
|
2635
2675
|
border-color: var(--select-dark-border, #4b5563);
|
|
@@ -2682,6 +2722,8 @@ class EnhancedSelect extends HTMLElement {
|
|
|
2682
2722
|
|
|
2683
2723
|
.option.active:not(.selected) {
|
|
2684
2724
|
background-color: var(--select-dark-option-active-bg, #374151);
|
|
2725
|
+
color: var(--select-dark-option-active-color, #f9fafb);
|
|
2726
|
+
outline: var(--select-dark-option-active-outline, 2px solid rgba(129, 140, 248, 0.55));
|
|
2685
2727
|
}
|
|
2686
2728
|
|
|
2687
2729
|
/* Group header in dark mode */
|
|
@@ -2689,9 +2731,6 @@ class EnhancedSelect extends HTMLElement {
|
|
|
2689
2731
|
color: var(--select-dark-group-header-color, var(--select-group-header-color, #6b7280));
|
|
2690
2732
|
background-color: var(--select-dark-group-header-bg, var(--select-group-header-bg, #374151));
|
|
2691
2733
|
}
|
|
2692
|
-
color: var(--select-dark-option-active-color, #f9fafb);
|
|
2693
|
-
outline: var(--select-dark-option-active-outline, 2px solid rgba(129, 140, 248, 0.55));
|
|
2694
|
-
}
|
|
2695
2734
|
|
|
2696
2735
|
.option.selected.active {
|
|
2697
2736
|
background-color: var(--select-dark-option-selected-active-bg, var(--select-dark-option-selected-bg, #3730a3));
|
|
@@ -2813,7 +2852,13 @@ class EnhancedSelect extends HTMLElement {
|
|
|
2813
2852
|
this._handleOpen();
|
|
2814
2853
|
}
|
|
2815
2854
|
else {
|
|
2816
|
-
//
|
|
2855
|
+
// Keep open while interacting directly with the input so users can
|
|
2856
|
+
// place cursor/type without accidental collapse.
|
|
2857
|
+
if (target === this._input) {
|
|
2858
|
+
this._input.focus();
|
|
2859
|
+
return;
|
|
2860
|
+
}
|
|
2861
|
+
// clicking other parts of the input container while open toggles close
|
|
2817
2862
|
this._handleClose();
|
|
2818
2863
|
}
|
|
2819
2864
|
// Focus the input (do not prevent default behavior)
|
|
@@ -3648,6 +3693,162 @@ class EnhancedSelect extends HTMLElement {
|
|
|
3648
3693
|
}
|
|
3649
3694
|
_emit(name, detail) {
|
|
3650
3695
|
this.dispatchEvent(new CustomEvent(name, { detail, bubbles: true, composed: true }));
|
|
3696
|
+
if (name !== 'diagnostic') {
|
|
3697
|
+
this._track('event', String(name), detail);
|
|
3698
|
+
}
|
|
3699
|
+
}
|
|
3700
|
+
_track(source, name, detail) {
|
|
3701
|
+
const cfg = this._config.tracking;
|
|
3702
|
+
if (!cfg?.enabled)
|
|
3703
|
+
return;
|
|
3704
|
+
if (source === 'event' && !cfg.events)
|
|
3705
|
+
return;
|
|
3706
|
+
if (source === 'style' && !cfg.styling)
|
|
3707
|
+
return;
|
|
3708
|
+
if (source === 'limitation' && !cfg.limitations)
|
|
3709
|
+
return;
|
|
3710
|
+
const entry = {
|
|
3711
|
+
timestamp: Date.now(),
|
|
3712
|
+
source,
|
|
3713
|
+
name,
|
|
3714
|
+
detail,
|
|
3715
|
+
};
|
|
3716
|
+
const bucket = source === 'event'
|
|
3717
|
+
? this._tracking.events
|
|
3718
|
+
: source === 'style'
|
|
3719
|
+
? this._tracking.styles
|
|
3720
|
+
: this._tracking.limitations;
|
|
3721
|
+
bucket.push(entry);
|
|
3722
|
+
const maxEntries = Math.max(10, cfg.maxEntries || 200);
|
|
3723
|
+
if (bucket.length > maxEntries) {
|
|
3724
|
+
bucket.splice(0, bucket.length - maxEntries);
|
|
3725
|
+
}
|
|
3726
|
+
if (cfg.emitDiagnostics) {
|
|
3727
|
+
this.dispatchEvent(new CustomEvent('diagnostic', {
|
|
3728
|
+
detail: entry,
|
|
3729
|
+
bubbles: true,
|
|
3730
|
+
composed: true,
|
|
3731
|
+
}));
|
|
3732
|
+
}
|
|
3733
|
+
}
|
|
3734
|
+
_getKnownLimitationDefinitions() {
|
|
3735
|
+
return [
|
|
3736
|
+
{
|
|
3737
|
+
id: 'variableItemHeight',
|
|
3738
|
+
title: 'Variable item height',
|
|
3739
|
+
description: 'Virtualization assumes fixed or estimated item heights; fully dynamic heights are not yet supported.',
|
|
3740
|
+
workaround: 'Use consistent item heights or set estimatedItemHeight to your dominant row size.',
|
|
3741
|
+
},
|
|
3742
|
+
{
|
|
3743
|
+
id: 'builtInFetchPaginationApi',
|
|
3744
|
+
title: 'Built-in fetch/pagination API',
|
|
3745
|
+
description: 'Core does not include a built-in fetchUrl/searchUrl pagination transport.',
|
|
3746
|
+
workaround: 'Use onSearch/onLoadMore callbacks and update data via setItems().',
|
|
3747
|
+
},
|
|
3748
|
+
{
|
|
3749
|
+
id: 'virtualizationOverheadSmallLists',
|
|
3750
|
+
title: 'Virtualization overhead for small lists',
|
|
3751
|
+
description: 'Virtualization can add slight overhead on very small lists.',
|
|
3752
|
+
workaround: 'Disable virtualization for tiny datasets when micro-latency is critical.',
|
|
3753
|
+
},
|
|
3754
|
+
{
|
|
3755
|
+
id: 'runtimeModeSwitching',
|
|
3756
|
+
title: 'Runtime single/multi mode switching',
|
|
3757
|
+
description: 'Switching between single and multi mode can require state reset for consistency.',
|
|
3758
|
+
workaround: 'Enable autoMitigateRuntimeModeSwitch or recreate/reset component state when toggling modes.',
|
|
3759
|
+
},
|
|
3760
|
+
{
|
|
3761
|
+
id: 'legacyBrowserSupport',
|
|
3762
|
+
title: 'Legacy browser support',
|
|
3763
|
+
description: 'Official support targets modern evergreen browsers.',
|
|
3764
|
+
},
|
|
3765
|
+
{
|
|
3766
|
+
id: 'webkitArchLinux',
|
|
3767
|
+
title: 'Playwright WebKit on Arch-based Linux',
|
|
3768
|
+
description: 'Native WebKit Playwright bundle depends on unavailable legacy system libraries on Arch-based distros.',
|
|
3769
|
+
workaround: 'Run WebKit E2E tests via Playwright Docker image.',
|
|
3770
|
+
},
|
|
3771
|
+
];
|
|
3772
|
+
}
|
|
3773
|
+
_evaluateLimitationStatus(id) {
|
|
3774
|
+
const policyMode = this._config.limitations?.policies?.[id]?.mode ?? 'default';
|
|
3775
|
+
if (policyMode === 'suppress')
|
|
3776
|
+
return 'suppressed';
|
|
3777
|
+
if (id === 'runtimeModeSwitching' && this._config.limitations?.autoMitigateRuntimeModeSwitch) {
|
|
3778
|
+
return 'mitigated';
|
|
3779
|
+
}
|
|
3780
|
+
return 'active';
|
|
3781
|
+
}
|
|
3782
|
+
getKnownLimitations() {
|
|
3783
|
+
return this._getKnownLimitationDefinitions().map((limitation) => {
|
|
3784
|
+
const mode = this._config.limitations?.policies?.[limitation.id]?.mode ?? 'default';
|
|
3785
|
+
return {
|
|
3786
|
+
...limitation,
|
|
3787
|
+
mode,
|
|
3788
|
+
status: this._evaluateLimitationStatus(limitation.id),
|
|
3789
|
+
};
|
|
3790
|
+
});
|
|
3791
|
+
}
|
|
3792
|
+
setLimitationPolicies(policies) {
|
|
3793
|
+
const next = {
|
|
3794
|
+
...(this._config.limitations?.policies || {}),
|
|
3795
|
+
...policies,
|
|
3796
|
+
};
|
|
3797
|
+
this.updateConfig({
|
|
3798
|
+
limitations: {
|
|
3799
|
+
...(this._config.limitations || { autoMitigateRuntimeModeSwitch: true, policies: {} }),
|
|
3800
|
+
policies: next,
|
|
3801
|
+
},
|
|
3802
|
+
});
|
|
3803
|
+
this._track('limitation', 'policiesUpdated', { policies: next });
|
|
3804
|
+
}
|
|
3805
|
+
getTrackingSnapshot() {
|
|
3806
|
+
return {
|
|
3807
|
+
events: [...this._tracking.events],
|
|
3808
|
+
styles: [...this._tracking.styles],
|
|
3809
|
+
limitations: [...this._tracking.limitations],
|
|
3810
|
+
};
|
|
3811
|
+
}
|
|
3812
|
+
clearTracking(source) {
|
|
3813
|
+
if (!source || source === 'all') {
|
|
3814
|
+
this._tracking.events = [];
|
|
3815
|
+
this._tracking.styles = [];
|
|
3816
|
+
this._tracking.limitations = [];
|
|
3817
|
+
return;
|
|
3818
|
+
}
|
|
3819
|
+
if (source === 'event')
|
|
3820
|
+
this._tracking.events = [];
|
|
3821
|
+
if (source === 'style')
|
|
3822
|
+
this._tracking.styles = [];
|
|
3823
|
+
if (source === 'limitation')
|
|
3824
|
+
this._tracking.limitations = [];
|
|
3825
|
+
}
|
|
3826
|
+
getCapabilities() {
|
|
3827
|
+
return {
|
|
3828
|
+
styling: {
|
|
3829
|
+
classMap: true,
|
|
3830
|
+
optionRenderer: true,
|
|
3831
|
+
groupHeaderRenderer: true,
|
|
3832
|
+
cssCustomProperties: true,
|
|
3833
|
+
shadowParts: true,
|
|
3834
|
+
globalStyleMirroring: true,
|
|
3835
|
+
},
|
|
3836
|
+
events: {
|
|
3837
|
+
emitted: ['select', 'open', 'close', 'search', 'change', 'loadMore', 'remove', 'clear', 'error', 'diagnostic'],
|
|
3838
|
+
diagnosticEvent: true,
|
|
3839
|
+
},
|
|
3840
|
+
functionality: {
|
|
3841
|
+
multiSelect: true,
|
|
3842
|
+
searchable: true,
|
|
3843
|
+
infiniteScroll: true,
|
|
3844
|
+
loadMore: true,
|
|
3845
|
+
clearControl: true,
|
|
3846
|
+
groupedItems: true,
|
|
3847
|
+
serverSideSelection: true,
|
|
3848
|
+
runtimeModeSwitchMitigation: Boolean(this._config.limitations?.autoMitigateRuntimeModeSwitch),
|
|
3849
|
+
},
|
|
3850
|
+
limitations: this.getKnownLimitations(),
|
|
3851
|
+
};
|
|
3651
3852
|
}
|
|
3652
3853
|
_emitChange() {
|
|
3653
3854
|
const selectedItems = Array.from(this._state.selectedItems.values());
|
|
@@ -3665,6 +3866,7 @@ class EnhancedSelect extends HTMLElement {
|
|
|
3665
3866
|
set optionRenderer(renderer) {
|
|
3666
3867
|
this._optionRenderer = renderer;
|
|
3667
3868
|
this._setGlobalStylesMirroring(Boolean(renderer || this._classMap));
|
|
3869
|
+
this._track('style', 'optionRendererChanged', { enabled: Boolean(renderer) });
|
|
3668
3870
|
this._renderOptions();
|
|
3669
3871
|
}
|
|
3670
3872
|
/**
|
|
@@ -3829,7 +4031,22 @@ class EnhancedSelect extends HTMLElement {
|
|
|
3829
4031
|
* Update component configuration
|
|
3830
4032
|
*/
|
|
3831
4033
|
updateConfig(config) {
|
|
3832
|
-
|
|
4034
|
+
const previousMode = this._config.selection.mode;
|
|
4035
|
+
this._config = this._mergeConfig(this._config, config);
|
|
4036
|
+
if (previousMode !== this._config.selection.mode &&
|
|
4037
|
+
this._config.limitations?.autoMitigateRuntimeModeSwitch) {
|
|
4038
|
+
this.clear();
|
|
4039
|
+
this._track('limitation', 'runtimeModeSwitchMitigated', {
|
|
4040
|
+
from: previousMode,
|
|
4041
|
+
to: this._config.selection.mode,
|
|
4042
|
+
});
|
|
4043
|
+
}
|
|
4044
|
+
else if (previousMode !== this._config.selection.mode) {
|
|
4045
|
+
this._track('limitation', 'runtimeModeSwitchDetected', {
|
|
4046
|
+
from: previousMode,
|
|
4047
|
+
to: this._config.selection.mode,
|
|
4048
|
+
});
|
|
4049
|
+
}
|
|
3833
4050
|
// Update input state based on new config
|
|
3834
4051
|
if (this._input) {
|
|
3835
4052
|
this._input.readOnly = !this._config.searchable;
|
|
@@ -3857,6 +4074,22 @@ class EnhancedSelect extends HTMLElement {
|
|
|
3857
4074
|
this._syncClearControlState();
|
|
3858
4075
|
this._renderOptions();
|
|
3859
4076
|
}
|
|
4077
|
+
_mergeConfig(target, source) {
|
|
4078
|
+
const result = { ...target };
|
|
4079
|
+
for (const key in source) {
|
|
4080
|
+
if (!Object.prototype.hasOwnProperty.call(source, key))
|
|
4081
|
+
continue;
|
|
4082
|
+
const sourceValue = source[key];
|
|
4083
|
+
const targetValue = result[key];
|
|
4084
|
+
if (sourceValue && typeof sourceValue === 'object' && !Array.isArray(sourceValue)) {
|
|
4085
|
+
result[key] = this._mergeConfig(targetValue && typeof targetValue === 'object' ? targetValue : {}, sourceValue);
|
|
4086
|
+
}
|
|
4087
|
+
else {
|
|
4088
|
+
result[key] = sourceValue;
|
|
4089
|
+
}
|
|
4090
|
+
}
|
|
4091
|
+
return result;
|
|
4092
|
+
}
|
|
3860
4093
|
_handleClearControlClick() {
|
|
3861
4094
|
const shouldClearSelection = this._config.clearControl.clearSelection !== false;
|
|
3862
4095
|
const shouldClearSearch = this._config.clearControl.clearSearch !== false;
|