@smilodon/core 1.4.3 → 1.4.5
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 +31 -0
- package/dist/index.cjs +260 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +260 -8
- 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 -8
- 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 +12 -1
- package/dist/types/src/config/global-config.d.ts +21 -0
- package/dist/types/src/index.d.ts +1 -1
- package/dist/types/src/types.d.ts +5 -0
- package/dist/types/src/utils/csp-styles.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1392,6 +1392,14 @@ const defaultConfig = {
|
|
|
1392
1392
|
expandLabel: 'Show more',
|
|
1393
1393
|
collapseLabel: 'Show less',
|
|
1394
1394
|
},
|
|
1395
|
+
clearControl: {
|
|
1396
|
+
enabled: false,
|
|
1397
|
+
clearSelection: true,
|
|
1398
|
+
clearSearch: true,
|
|
1399
|
+
hideWhenEmpty: true,
|
|
1400
|
+
ariaLabel: 'Clear selection and search',
|
|
1401
|
+
icon: '×',
|
|
1402
|
+
},
|
|
1395
1403
|
callbacks: {},
|
|
1396
1404
|
enabled: true,
|
|
1397
1405
|
searchable: false,
|
|
@@ -1496,10 +1504,15 @@ class SelectOption extends HTMLElement {
|
|
|
1496
1504
|
display: flex;
|
|
1497
1505
|
align-items: center;
|
|
1498
1506
|
justify-content: space-between;
|
|
1499
|
-
padding: 8px 12px;
|
|
1507
|
+
padding: var(--select-option-padding, 8px 12px);
|
|
1500
1508
|
cursor: pointer;
|
|
1501
1509
|
user-select: none;
|
|
1502
|
-
transition: background-color 0.2s ease;
|
|
1510
|
+
transition: var(--select-option-transition, background-color 0.2s ease);
|
|
1511
|
+
border: var(--select-option-border, none);
|
|
1512
|
+
border-bottom: var(--select-option-border-bottom, none);
|
|
1513
|
+
border-radius: var(--select-option-border-radius, 0);
|
|
1514
|
+
box-shadow: var(--select-option-shadow, none);
|
|
1515
|
+
transform: var(--select-option-transform, none);
|
|
1503
1516
|
}
|
|
1504
1517
|
|
|
1505
1518
|
.option-container:hover {
|
|
@@ -1509,6 +1522,20 @@ class SelectOption extends HTMLElement {
|
|
|
1509
1522
|
.option-container.selected {
|
|
1510
1523
|
background-color: var(--select-option-selected-bg, #e3f2fd);
|
|
1511
1524
|
color: var(--select-option-selected-color, #1976d2);
|
|
1525
|
+
border: var(--select-option-selected-border, var(--select-option-border, none));
|
|
1526
|
+
border-bottom: var(--select-option-selected-border-bottom, var(--select-option-border-bottom, none));
|
|
1527
|
+
border-radius: var(--select-option-selected-border-radius, var(--select-option-border-radius, 0));
|
|
1528
|
+
box-shadow: var(--select-option-selected-shadow, var(--select-option-shadow, none));
|
|
1529
|
+
transform: var(--select-option-selected-transform, var(--select-option-transform, none));
|
|
1530
|
+
}
|
|
1531
|
+
|
|
1532
|
+
.option-container.selected:hover {
|
|
1533
|
+
background-color: var(--select-option-selected-hover-bg, var(--select-option-selected-bg, #e3f2fd));
|
|
1534
|
+
color: var(--select-option-selected-hover-color, var(--select-option-selected-color, #1976d2));
|
|
1535
|
+
border: var(--select-option-selected-hover-border, var(--select-option-selected-border, var(--select-option-border, none)));
|
|
1536
|
+
border-bottom: var(--select-option-selected-hover-border-bottom, var(--select-option-selected-border-bottom, var(--select-option-border-bottom, none)));
|
|
1537
|
+
box-shadow: var(--select-option-selected-hover-shadow, var(--select-option-selected-shadow, var(--select-option-shadow, none)));
|
|
1538
|
+
transform: var(--select-option-selected-hover-transform, var(--select-option-selected-transform, var(--select-option-transform, none)));
|
|
1512
1539
|
}
|
|
1513
1540
|
|
|
1514
1541
|
.option-container.active {
|
|
@@ -1816,6 +1843,16 @@ if (!customElements.get('select-option')) {
|
|
|
1816
1843
|
* server-side selection, and full customization
|
|
1817
1844
|
*/
|
|
1818
1845
|
class EnhancedSelect extends HTMLElement {
|
|
1846
|
+
get classMap() {
|
|
1847
|
+
return this._classMap;
|
|
1848
|
+
}
|
|
1849
|
+
set classMap(map) {
|
|
1850
|
+
this._classMap = map;
|
|
1851
|
+
this._setGlobalStylesMirroring(Boolean(this._optionRenderer || map));
|
|
1852
|
+
if (!this.isConnected)
|
|
1853
|
+
return;
|
|
1854
|
+
this._renderOptions();
|
|
1855
|
+
}
|
|
1819
1856
|
constructor() {
|
|
1820
1857
|
super();
|
|
1821
1858
|
this._pageCache = {};
|
|
@@ -1859,6 +1896,7 @@ class EnhancedSelect extends HTMLElement {
|
|
|
1859
1896
|
this._inputContainer = this._createInputContainer();
|
|
1860
1897
|
this._input = this._createInput();
|
|
1861
1898
|
this._arrowContainer = this._createArrowContainer();
|
|
1899
|
+
this._clearControl = this._createClearControl();
|
|
1862
1900
|
this._dropdown = this._createDropdown();
|
|
1863
1901
|
this._optionsContainer = this._createOptionsContainer();
|
|
1864
1902
|
this._liveRegion = this._createLiveRegion();
|
|
@@ -2072,8 +2110,25 @@ class EnhancedSelect extends HTMLElement {
|
|
|
2072
2110
|
`;
|
|
2073
2111
|
return container;
|
|
2074
2112
|
}
|
|
2113
|
+
_createClearControl() {
|
|
2114
|
+
const button = document.createElement('button');
|
|
2115
|
+
button.type = 'button';
|
|
2116
|
+
button.className = 'clear-control-button';
|
|
2117
|
+
button.setAttribute('part', 'clear-button');
|
|
2118
|
+
const icon = document.createElement('span');
|
|
2119
|
+
icon.className = 'clear-control-icon';
|
|
2120
|
+
icon.setAttribute('part', 'clear-icon');
|
|
2121
|
+
icon.textContent = this._config.clearControl.icon || '×';
|
|
2122
|
+
button.setAttribute('aria-label', this._config.clearControl.ariaLabel || 'Clear selection and search');
|
|
2123
|
+
button.appendChild(icon);
|
|
2124
|
+
this._clearControlIcon = icon;
|
|
2125
|
+
return button;
|
|
2126
|
+
}
|
|
2075
2127
|
_assembleDOM() {
|
|
2076
2128
|
this._inputContainer.appendChild(this._input);
|
|
2129
|
+
if (this._clearControl) {
|
|
2130
|
+
this._inputContainer.appendChild(this._clearControl);
|
|
2131
|
+
}
|
|
2077
2132
|
if (this._arrowContainer) {
|
|
2078
2133
|
this._inputContainer.appendChild(this._arrowContainer);
|
|
2079
2134
|
}
|
|
@@ -2089,6 +2144,7 @@ class EnhancedSelect extends HTMLElement {
|
|
|
2089
2144
|
this._dropdown.id = listboxId;
|
|
2090
2145
|
this._input.setAttribute('aria-controls', listboxId);
|
|
2091
2146
|
this._input.setAttribute('aria-owns', listboxId);
|
|
2147
|
+
this._syncClearControlState();
|
|
2092
2148
|
}
|
|
2093
2149
|
_initializeStyles() {
|
|
2094
2150
|
const style = document.createElement('style');
|
|
@@ -2162,6 +2218,58 @@ class EnhancedSelect extends HTMLElement {
|
|
|
2162
2218
|
border-radius: var(--select-arrow-border-radius, 0 4px 4px 0);
|
|
2163
2219
|
z-index: 2;
|
|
2164
2220
|
}
|
|
2221
|
+
|
|
2222
|
+
.input-container.has-clear-control {
|
|
2223
|
+
padding: var(--select-input-padding-with-clear, 6px 84px 6px 8px);
|
|
2224
|
+
}
|
|
2225
|
+
|
|
2226
|
+
.input-container.has-clear-control::after {
|
|
2227
|
+
right: var(--select-separator-position-with-clear, 72px);
|
|
2228
|
+
}
|
|
2229
|
+
|
|
2230
|
+
.dropdown-arrow-container.with-clear-control {
|
|
2231
|
+
right: var(--select-arrow-right-with-clear, 32px);
|
|
2232
|
+
}
|
|
2233
|
+
|
|
2234
|
+
.clear-control-button {
|
|
2235
|
+
position: absolute;
|
|
2236
|
+
top: 50%;
|
|
2237
|
+
right: var(--select-clear-button-right, 6px);
|
|
2238
|
+
transform: translateY(-50%);
|
|
2239
|
+
width: var(--select-clear-button-size, 24px);
|
|
2240
|
+
height: var(--select-clear-button-size, 24px);
|
|
2241
|
+
border: var(--select-clear-button-border, none);
|
|
2242
|
+
border-radius: var(--select-clear-button-radius, 999px);
|
|
2243
|
+
background: var(--select-clear-button-bg, transparent);
|
|
2244
|
+
color: var(--select-clear-button-color, #6b7280);
|
|
2245
|
+
display: inline-flex;
|
|
2246
|
+
align-items: center;
|
|
2247
|
+
justify-content: center;
|
|
2248
|
+
cursor: pointer;
|
|
2249
|
+
z-index: 3;
|
|
2250
|
+
transition: var(--select-clear-button-transition, all 0.2s ease);
|
|
2251
|
+
}
|
|
2252
|
+
|
|
2253
|
+
.clear-control-button:hover {
|
|
2254
|
+
background: var(--select-clear-button-hover-bg, rgba(0, 0, 0, 0.06));
|
|
2255
|
+
color: var(--select-clear-button-hover-color, #111827);
|
|
2256
|
+
}
|
|
2257
|
+
|
|
2258
|
+
.clear-control-button:focus-visible {
|
|
2259
|
+
outline: var(--select-clear-button-focus-outline, 2px solid rgba(102, 126, 234, 0.55));
|
|
2260
|
+
outline-offset: 1px;
|
|
2261
|
+
}
|
|
2262
|
+
|
|
2263
|
+
.clear-control-button[hidden] {
|
|
2264
|
+
display: none;
|
|
2265
|
+
}
|
|
2266
|
+
|
|
2267
|
+
.clear-control-icon {
|
|
2268
|
+
font-size: var(--select-clear-icon-size, 16px);
|
|
2269
|
+
line-height: 1;
|
|
2270
|
+
font-weight: var(--select-clear-icon-weight, 500);
|
|
2271
|
+
pointer-events: none;
|
|
2272
|
+
}
|
|
2165
2273
|
|
|
2166
2274
|
.dropdown-arrow-container:hover {
|
|
2167
2275
|
background-color: var(--select-arrow-hover-bg, rgba(102, 126, 234, 0.08));
|
|
@@ -2289,6 +2397,9 @@ class EnhancedSelect extends HTMLElement {
|
|
|
2289
2397
|
line-height: var(--select-option-line-height, 1.5);
|
|
2290
2398
|
border: var(--select-option-border, none);
|
|
2291
2399
|
border-bottom: var(--select-option-border-bottom, none);
|
|
2400
|
+
border-radius: var(--select-option-border-radius, 0);
|
|
2401
|
+
box-shadow: var(--select-option-shadow, none);
|
|
2402
|
+
transform: var(--select-option-transform, none);
|
|
2292
2403
|
}
|
|
2293
2404
|
|
|
2294
2405
|
.option:hover {
|
|
@@ -2300,18 +2411,47 @@ class EnhancedSelect extends HTMLElement {
|
|
|
2300
2411
|
background-color: var(--select-option-selected-bg, #e0e7ff);
|
|
2301
2412
|
color: var(--select-option-selected-color, #4338ca);
|
|
2302
2413
|
font-weight: var(--select-option-selected-weight, 500);
|
|
2414
|
+
border: var(--select-option-selected-border, var(--select-option-border, none));
|
|
2415
|
+
border-bottom: var(--select-option-selected-border-bottom, var(--select-option-border-bottom, none));
|
|
2416
|
+
border-radius: var(--select-option-selected-border-radius, var(--select-option-border-radius, 0));
|
|
2417
|
+
box-shadow: var(--select-option-selected-shadow, var(--select-option-shadow, none));
|
|
2418
|
+
transform: var(--select-option-selected-transform, var(--select-option-transform, none));
|
|
2419
|
+
}
|
|
2420
|
+
|
|
2421
|
+
.option.selected:hover {
|
|
2422
|
+
background-color: var(--select-option-selected-hover-bg, var(--select-option-selected-bg, #e0e7ff));
|
|
2423
|
+
color: var(--select-option-selected-hover-color, var(--select-option-selected-color, #4338ca));
|
|
2424
|
+
border: var(--select-option-selected-hover-border, var(--select-option-selected-border, var(--select-option-border, none)));
|
|
2425
|
+
border-bottom: var(--select-option-selected-hover-border-bottom, var(--select-option-selected-border-bottom, var(--select-option-border-bottom, none)));
|
|
2426
|
+
box-shadow: var(--select-option-selected-hover-shadow, var(--select-option-selected-shadow, var(--select-option-shadow, none)));
|
|
2427
|
+
transform: var(--select-option-selected-hover-transform, var(--select-option-selected-transform, var(--select-option-transform, none)));
|
|
2303
2428
|
}
|
|
2304
2429
|
|
|
2305
|
-
.option.active {
|
|
2430
|
+
.option.active:not(.selected) {
|
|
2306
2431
|
background-color: var(--select-option-active-bg, #f3f4f6);
|
|
2307
2432
|
color: var(--select-option-active-color, #1f2937);
|
|
2308
2433
|
outline: var(--select-option-active-outline, 2px solid rgba(99, 102, 241, 0.45));
|
|
2309
2434
|
outline-offset: -2px;
|
|
2310
2435
|
}
|
|
2311
2436
|
|
|
2312
|
-
.option
|
|
2437
|
+
.option.selected.active {
|
|
2438
|
+
background-color: var(--select-option-selected-active-bg, var(--select-option-selected-bg, #e0e7ff));
|
|
2439
|
+
color: var(--select-option-selected-active-color, var(--select-option-selected-color, #4338ca));
|
|
2440
|
+
border: var(--select-option-selected-active-border, var(--select-option-selected-border, var(--select-option-border, none)));
|
|
2441
|
+
border-bottom: var(--select-option-selected-active-border-bottom, var(--select-option-selected-border-bottom, var(--select-option-border-bottom, none)));
|
|
2442
|
+
box-shadow: var(--select-option-selected-active-shadow, var(--select-option-selected-shadow, var(--select-option-shadow, none)));
|
|
2443
|
+
transform: var(--select-option-selected-active-transform, var(--select-option-selected-transform, var(--select-option-transform, none)));
|
|
2444
|
+
outline: var(--select-option-selected-active-outline, var(--select-option-active-outline, 2px solid rgba(99, 102, 241, 0.45)));
|
|
2445
|
+
outline-offset: -2px;
|
|
2446
|
+
}
|
|
2447
|
+
|
|
2448
|
+
.option:active:not(.selected) {
|
|
2313
2449
|
background-color: var(--select-option-pressed-bg, #e5e7eb);
|
|
2314
2450
|
}
|
|
2451
|
+
|
|
2452
|
+
.option.selected:active {
|
|
2453
|
+
background-color: var(--select-option-selected-pressed-bg, var(--select-option-selected-hover-bg, var(--select-option-selected-bg, #e0e7ff)));
|
|
2454
|
+
}
|
|
2315
2455
|
|
|
2316
2456
|
.load-more-container {
|
|
2317
2457
|
padding: var(--select-load-more-padding, 12px);
|
|
@@ -2457,14 +2597,38 @@ class EnhancedSelect extends HTMLElement {
|
|
|
2457
2597
|
.option.selected {
|
|
2458
2598
|
background-color: var(--select-dark-option-selected-bg, #3730a3);
|
|
2459
2599
|
color: var(--select-dark-option-selected-text, #e0e7ff);
|
|
2600
|
+
border: var(--select-dark-option-selected-border, var(--select-option-selected-border, var(--select-option-border, none)));
|
|
2601
|
+
border-bottom: var(--select-dark-option-selected-border-bottom, var(--select-option-selected-border-bottom, var(--select-option-border-bottom, none)));
|
|
2602
|
+
box-shadow: var(--select-dark-option-selected-shadow, var(--select-option-selected-shadow, var(--select-option-shadow, none)));
|
|
2603
|
+
transform: var(--select-dark-option-selected-transform, var(--select-option-selected-transform, var(--select-option-transform, none)));
|
|
2604
|
+
}
|
|
2605
|
+
|
|
2606
|
+
.option.selected:hover {
|
|
2607
|
+
background-color: var(--select-dark-option-selected-hover-bg, var(--select-dark-option-selected-bg, #3730a3));
|
|
2608
|
+
color: var(--select-dark-option-selected-hover-color, var(--select-dark-option-selected-text, #e0e7ff));
|
|
2609
|
+
border: var(--select-dark-option-selected-hover-border, var(--select-dark-option-selected-border, var(--select-option-selected-hover-border, var(--select-option-selected-border, var(--select-option-border, none)))));
|
|
2610
|
+
border-bottom: var(--select-dark-option-selected-hover-border-bottom, var(--select-dark-option-selected-border-bottom, var(--select-option-selected-hover-border-bottom, var(--select-option-selected-border-bottom, var(--select-option-border-bottom, none)))));
|
|
2611
|
+
box-shadow: var(--select-dark-option-selected-hover-shadow, var(--select-dark-option-selected-shadow, var(--select-option-selected-hover-shadow, var(--select-option-selected-shadow, var(--select-option-shadow, none)))));
|
|
2612
|
+
transform: var(--select-dark-option-selected-hover-transform, var(--select-dark-option-selected-transform, var(--select-option-selected-hover-transform, var(--select-option-selected-transform, var(--select-option-transform, none)))));
|
|
2460
2613
|
}
|
|
2461
2614
|
|
|
2462
|
-
.option.active {
|
|
2615
|
+
.option.active:not(.selected) {
|
|
2463
2616
|
background-color: var(--select-dark-option-active-bg, #374151);
|
|
2464
2617
|
color: var(--select-dark-option-active-color, #f9fafb);
|
|
2465
2618
|
outline: var(--select-dark-option-active-outline, 2px solid rgba(129, 140, 248, 0.55));
|
|
2466
2619
|
}
|
|
2467
2620
|
|
|
2621
|
+
.option.selected.active {
|
|
2622
|
+
background-color: var(--select-dark-option-selected-active-bg, var(--select-dark-option-selected-bg, #3730a3));
|
|
2623
|
+
color: var(--select-dark-option-selected-active-color, var(--select-dark-option-selected-text, #e0e7ff));
|
|
2624
|
+
border: var(--select-dark-option-selected-active-border, var(--select-dark-option-selected-border, var(--select-option-selected-active-border, var(--select-option-selected-border, var(--select-option-border, none)))));
|
|
2625
|
+
border-bottom: var(--select-dark-option-selected-active-border-bottom, var(--select-dark-option-selected-border-bottom, var(--select-option-selected-active-border-bottom, var(--select-option-selected-border-bottom, var(--select-option-border-bottom, none)))));
|
|
2626
|
+
box-shadow: var(--select-dark-option-selected-active-shadow, var(--select-dark-option-selected-shadow, var(--select-option-selected-active-shadow, var(--select-option-selected-shadow, var(--select-option-shadow, none)))));
|
|
2627
|
+
transform: var(--select-dark-option-selected-active-transform, var(--select-dark-option-selected-transform, var(--select-option-selected-active-transform, var(--select-option-selected-transform, var(--select-option-transform, none)))));
|
|
2628
|
+
outline: var(--select-dark-option-selected-active-outline, var(--select-dark-option-active-outline, var(--select-option-selected-active-outline, var(--select-option-active-outline, 2px solid rgba(129, 140, 248, 0.55)))));
|
|
2629
|
+
outline-offset: -2px;
|
|
2630
|
+
}
|
|
2631
|
+
|
|
2468
2632
|
.selection-badge {
|
|
2469
2633
|
background: var(--select-dark-badge-bg, #4f46e5);
|
|
2470
2634
|
color: var(--select-dark-badge-color, #eef2ff);
|
|
@@ -2549,6 +2713,17 @@ class EnhancedSelect extends HTMLElement {
|
|
|
2549
2713
|
};
|
|
2550
2714
|
this._arrowContainer.addEventListener('click', this._boundArrowClick);
|
|
2551
2715
|
}
|
|
2716
|
+
if (this._clearControl) {
|
|
2717
|
+
this._clearControl.addEventListener('pointerdown', (e) => {
|
|
2718
|
+
e.stopPropagation();
|
|
2719
|
+
e.preventDefault();
|
|
2720
|
+
});
|
|
2721
|
+
this._clearControl.addEventListener('click', (e) => {
|
|
2722
|
+
e.stopPropagation();
|
|
2723
|
+
e.preventDefault();
|
|
2724
|
+
this._handleClearControlClick();
|
|
2725
|
+
});
|
|
2726
|
+
}
|
|
2552
2727
|
// Input container click - focus input and open dropdown
|
|
2553
2728
|
this._inputContainer.addEventListener('pointerdown', (e) => {
|
|
2554
2729
|
const target = e.target;
|
|
@@ -2556,6 +2731,8 @@ class EnhancedSelect extends HTMLElement {
|
|
|
2556
2731
|
return;
|
|
2557
2732
|
if (target && target.closest('.dropdown-arrow-container'))
|
|
2558
2733
|
return;
|
|
2734
|
+
if (target && target.closest('.clear-control-button'))
|
|
2735
|
+
return;
|
|
2559
2736
|
if (!this._state.isOpen) {
|
|
2560
2737
|
this._handleOpen();
|
|
2561
2738
|
}
|
|
@@ -2768,6 +2945,7 @@ class EnhancedSelect extends HTMLElement {
|
|
|
2768
2945
|
}
|
|
2769
2946
|
_handleSearch(query) {
|
|
2770
2947
|
this._state.searchQuery = query;
|
|
2948
|
+
this._syncClearControlState();
|
|
2771
2949
|
if (query.length > 0) {
|
|
2772
2950
|
this._perfMark('smilodon-search-input-last');
|
|
2773
2951
|
this._pendingSearchRenderMark = true;
|
|
@@ -2945,7 +3123,9 @@ class EnhancedSelect extends HTMLElement {
|
|
|
2945
3123
|
option.classList.add('smilodon-option--active');
|
|
2946
3124
|
option.setAttribute('aria-selected', 'true');
|
|
2947
3125
|
}
|
|
2948
|
-
option.scrollIntoView
|
|
3126
|
+
if (typeof option.scrollIntoView === 'function') {
|
|
3127
|
+
option.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
|
|
3128
|
+
}
|
|
2949
3129
|
// Announce position for screen readers
|
|
2950
3130
|
const total = options.length;
|
|
2951
3131
|
this._announce(`Item ${index + 1} of ${total}`);
|
|
@@ -3072,6 +3252,10 @@ class EnhancedSelect extends HTMLElement {
|
|
|
3072
3252
|
const item = this._state.loadedItems[index];
|
|
3073
3253
|
if (!item)
|
|
3074
3254
|
return;
|
|
3255
|
+
// Keep active/focus styling aligned with the most recently interacted option.
|
|
3256
|
+
// Without this, a previously selected item may retain active classes/styles
|
|
3257
|
+
// after selecting a different option.
|
|
3258
|
+
this._state.activeIndex = index;
|
|
3075
3259
|
const isCurrentlySelected = this._state.selectedIndices.has(index);
|
|
3076
3260
|
if (this._config.selection.mode === 'single') {
|
|
3077
3261
|
// Single select: clear previous and select new
|
|
@@ -3196,6 +3380,7 @@ class EnhancedSelect extends HTMLElement {
|
|
|
3196
3380
|
this._inputContainer.insertBefore(badge, this._input);
|
|
3197
3381
|
});
|
|
3198
3382
|
}
|
|
3383
|
+
this._syncClearControlState();
|
|
3199
3384
|
}
|
|
3200
3385
|
_renderOptionsWithAnimation() {
|
|
3201
3386
|
// Add fade-out animation
|
|
@@ -3311,7 +3496,7 @@ class EnhancedSelect extends HTMLElement {
|
|
|
3311
3496
|
}
|
|
3312
3497
|
set optionRenderer(renderer) {
|
|
3313
3498
|
this._optionRenderer = renderer;
|
|
3314
|
-
this._setGlobalStylesMirroring(Boolean(renderer));
|
|
3499
|
+
this._setGlobalStylesMirroring(Boolean(renderer || this._classMap));
|
|
3315
3500
|
this._renderOptions();
|
|
3316
3501
|
}
|
|
3317
3502
|
/**
|
|
@@ -3444,6 +3629,21 @@ class EnhancedSelect extends HTMLElement {
|
|
|
3444
3629
|
this._renderOptions();
|
|
3445
3630
|
this._updateInputDisplay();
|
|
3446
3631
|
this._emitChange();
|
|
3632
|
+
this._syncClearControlState();
|
|
3633
|
+
}
|
|
3634
|
+
/**
|
|
3635
|
+
* Clear search query and restore full option list
|
|
3636
|
+
*/
|
|
3637
|
+
clearSearch() {
|
|
3638
|
+
this._state.searchQuery = '';
|
|
3639
|
+
if (this._config.searchable) {
|
|
3640
|
+
this._input.value = '';
|
|
3641
|
+
if (this._state.selectedIndices.size > 0) {
|
|
3642
|
+
this._updateInputDisplay();
|
|
3643
|
+
}
|
|
3644
|
+
}
|
|
3645
|
+
this._renderOptions();
|
|
3646
|
+
this._syncClearControlState();
|
|
3447
3647
|
}
|
|
3448
3648
|
/**
|
|
3449
3649
|
* Open dropdown
|
|
@@ -3470,6 +3670,12 @@ class EnhancedSelect extends HTMLElement {
|
|
|
3470
3670
|
this._input.placeholder = this._config.placeholder || 'Select an option...';
|
|
3471
3671
|
}
|
|
3472
3672
|
}
|
|
3673
|
+
if (this._clearControl) {
|
|
3674
|
+
this._clearControl.setAttribute('aria-label', this._config.clearControl.ariaLabel || 'Clear selection and search');
|
|
3675
|
+
}
|
|
3676
|
+
if (this._clearControlIcon) {
|
|
3677
|
+
this._clearControlIcon.textContent = this._config.clearControl.icon || '×';
|
|
3678
|
+
}
|
|
3473
3679
|
if (this._dropdown) {
|
|
3474
3680
|
if (this._config.selection.mode === 'multi') {
|
|
3475
3681
|
this._dropdown.setAttribute('aria-multiselectable', 'true');
|
|
@@ -3480,8 +3686,47 @@ class EnhancedSelect extends HTMLElement {
|
|
|
3480
3686
|
}
|
|
3481
3687
|
// Re-initialize observers in case infinite scroll was enabled/disabled
|
|
3482
3688
|
this._initializeObservers();
|
|
3689
|
+
this._syncClearControlState();
|
|
3483
3690
|
this._renderOptions();
|
|
3484
3691
|
}
|
|
3692
|
+
_handleClearControlClick() {
|
|
3693
|
+
const shouldClearSelection = this._config.clearControl.clearSelection !== false;
|
|
3694
|
+
const shouldClearSearch = this._config.clearControl.clearSearch !== false;
|
|
3695
|
+
const hadSelection = this._state.selectedIndices.size > 0;
|
|
3696
|
+
const hadSearch = this._state.searchQuery.length > 0;
|
|
3697
|
+
if (shouldClearSelection && hadSelection) {
|
|
3698
|
+
this.clear();
|
|
3699
|
+
}
|
|
3700
|
+
if (shouldClearSearch && hadSearch) {
|
|
3701
|
+
this.clearSearch();
|
|
3702
|
+
}
|
|
3703
|
+
this._emit('clear', {
|
|
3704
|
+
clearedSelection: shouldClearSelection && hadSelection,
|
|
3705
|
+
clearedSearch: shouldClearSearch && hadSearch,
|
|
3706
|
+
});
|
|
3707
|
+
this._config.callbacks.onClear?.({
|
|
3708
|
+
clearedSelection: shouldClearSelection && hadSelection,
|
|
3709
|
+
clearedSearch: shouldClearSearch && hadSearch,
|
|
3710
|
+
});
|
|
3711
|
+
this._input.focus();
|
|
3712
|
+
}
|
|
3713
|
+
_syncClearControlState() {
|
|
3714
|
+
if (!this._clearControl || !this._inputContainer || !this._arrowContainer)
|
|
3715
|
+
return;
|
|
3716
|
+
const enabled = this._config.clearControl.enabled === true;
|
|
3717
|
+
const hasSelection = this._state.selectedIndices.size > 0;
|
|
3718
|
+
const hasSearch = this._state.searchQuery.length > 0;
|
|
3719
|
+
const clearSelection = this._config.clearControl.clearSelection !== false;
|
|
3720
|
+
const clearSearch = this._config.clearControl.clearSearch !== false;
|
|
3721
|
+
const hasSomethingToClear = (clearSelection && hasSelection) || (clearSearch && hasSearch);
|
|
3722
|
+
const hideWhenEmpty = this._config.clearControl.hideWhenEmpty !== false;
|
|
3723
|
+
const visible = enabled && (!hideWhenEmpty || hasSomethingToClear);
|
|
3724
|
+
this._inputContainer.classList.toggle('has-clear-control', enabled);
|
|
3725
|
+
this._arrowContainer.classList.toggle('with-clear-control', enabled);
|
|
3726
|
+
this._clearControl.hidden = !visible;
|
|
3727
|
+
this._clearControl.disabled = !hasSomethingToClear;
|
|
3728
|
+
this._clearControl.setAttribute('aria-hidden', String(!visible));
|
|
3729
|
+
}
|
|
3485
3730
|
/**
|
|
3486
3731
|
* Set error state
|
|
3487
3732
|
*/
|
|
@@ -4769,10 +5014,17 @@ const shadowDOMStyles = `
|
|
|
4769
5014
|
color: var(--ns-item-selected-color, #0066cc);
|
|
4770
5015
|
}
|
|
4771
5016
|
|
|
4772
|
-
.ns-item[data-active="true"] {
|
|
5017
|
+
.ns-item[data-active="true"]:not([aria-selected="true"]) {
|
|
4773
5018
|
background: var(--ns-item-active-bg, rgba(0, 102, 204, 0.2));
|
|
4774
5019
|
}
|
|
4775
5020
|
|
|
5021
|
+
.ns-item[aria-selected="true"][data-active="true"] {
|
|
5022
|
+
background: var(--ns-item-selected-active-bg, var(--ns-item-selected-bg, rgba(0, 102, 204, 0.1)));
|
|
5023
|
+
color: var(--ns-item-selected-active-color, var(--ns-item-selected-color, #0066cc));
|
|
5024
|
+
outline: var(--ns-item-selected-active-outline, 2px solid #0066cc);
|
|
5025
|
+
outline-offset: -2px;
|
|
5026
|
+
}
|
|
5027
|
+
|
|
4776
5028
|
.ns-item[aria-disabled="true"] {
|
|
4777
5029
|
opacity: 0.5;
|
|
4778
5030
|
cursor: not-allowed;
|