@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 CHANGED
@@ -136,6 +136,31 @@ See the [main documentation](https://github.com/navidrezadoost/smilodon#readme)
136
136
 
137
137
  ## API Reference
138
138
 
139
+ ### Clear Control (Selection/Search Reset)
140
+
141
+ ```javascript
142
+ const select = document.querySelector('enhanced-select');
143
+
144
+ select.updateConfig({
145
+ clearControl: {
146
+ enabled: true,
147
+ clearSelection: true,
148
+ clearSearch: true,
149
+ hideWhenEmpty: true,
150
+ ariaLabel: 'Clear selected and searched values',
151
+ icon: '✕',
152
+ }
153
+ });
154
+
155
+ select.addEventListener('clear', (e) => {
156
+ console.log(e.detail); // { clearedSelection: boolean, clearedSearch: boolean }
157
+ });
158
+ ```
159
+
160
+ Style hooks:
161
+ - Parts: `::part(clear-button)`, `::part(clear-icon)`
162
+ - Tokens: `--select-clear-button-*`, `--select-clear-icon-*`, `--select-input-padding-with-clear`
163
+
139
164
  ### Properties
140
165
 
141
166
  ```typescript
@@ -560,6 +585,9 @@ enhanced-select {
560
585
  /* Selected state */
561
586
  --select-option-selected-bg: #e0e7ff;
562
587
  --select-option-selected-color: #4338ca;
588
+ --select-option-selected-border: 1px solid #4338ca;
589
+ --select-option-selected-hover-bg: #c7d2fe;
590
+ --select-option-selected-hover-border: 1px solid #3730a3;
563
591
 
564
592
  /* Active/focused state */
565
593
  --select-option-active-bg: #f3f4f6;
@@ -610,6 +638,9 @@ enhanced-select.dark-mode {
610
638
  --select-option-hover-color /* Hover text color (#1f2937) */
611
639
  --select-option-selected-bg /* Selected background (#e0e7ff) */
612
640
  --select-option-selected-color /* Selected text color (#4338ca) */
641
+ --select-option-selected-border /* Selected border (inherits option border by default) */
642
+ --select-option-selected-hover-bg /* Selected+hover background (inherits selected bg by default) */
643
+ --select-option-selected-hover-border /* Selected+hover border (inherits selected border by default) */
613
644
  --select-option-active-bg /* Active background (#f3f4f6) */
614
645
  --select-option-active-color /* Active text color (#1f2937) */
615
646
  --select-dropdown-bg /* Dropdown background (white) */
package/dist/index.cjs CHANGED
@@ -1394,6 +1394,14 @@ const defaultConfig = {
1394
1394
  expandLabel: 'Show more',
1395
1395
  collapseLabel: 'Show less',
1396
1396
  },
1397
+ clearControl: {
1398
+ enabled: false,
1399
+ clearSelection: true,
1400
+ clearSearch: true,
1401
+ hideWhenEmpty: true,
1402
+ ariaLabel: 'Clear selection and search',
1403
+ icon: '×',
1404
+ },
1397
1405
  callbacks: {},
1398
1406
  enabled: true,
1399
1407
  searchable: false,
@@ -1498,10 +1506,15 @@ class SelectOption extends HTMLElement {
1498
1506
  display: flex;
1499
1507
  align-items: center;
1500
1508
  justify-content: space-between;
1501
- padding: 8px 12px;
1509
+ padding: var(--select-option-padding, 8px 12px);
1502
1510
  cursor: pointer;
1503
1511
  user-select: none;
1504
- transition: background-color 0.2s ease;
1512
+ transition: var(--select-option-transition, background-color 0.2s ease);
1513
+ border: var(--select-option-border, none);
1514
+ border-bottom: var(--select-option-border-bottom, none);
1515
+ border-radius: var(--select-option-border-radius, 0);
1516
+ box-shadow: var(--select-option-shadow, none);
1517
+ transform: var(--select-option-transform, none);
1505
1518
  }
1506
1519
 
1507
1520
  .option-container:hover {
@@ -1511,6 +1524,20 @@ class SelectOption extends HTMLElement {
1511
1524
  .option-container.selected {
1512
1525
  background-color: var(--select-option-selected-bg, #e3f2fd);
1513
1526
  color: var(--select-option-selected-color, #1976d2);
1527
+ border: var(--select-option-selected-border, var(--select-option-border, none));
1528
+ border-bottom: var(--select-option-selected-border-bottom, var(--select-option-border-bottom, none));
1529
+ border-radius: var(--select-option-selected-border-radius, var(--select-option-border-radius, 0));
1530
+ box-shadow: var(--select-option-selected-shadow, var(--select-option-shadow, none));
1531
+ transform: var(--select-option-selected-transform, var(--select-option-transform, none));
1532
+ }
1533
+
1534
+ .option-container.selected:hover {
1535
+ background-color: var(--select-option-selected-hover-bg, var(--select-option-selected-bg, #e3f2fd));
1536
+ color: var(--select-option-selected-hover-color, var(--select-option-selected-color, #1976d2));
1537
+ border: var(--select-option-selected-hover-border, var(--select-option-selected-border, var(--select-option-border, none)));
1538
+ border-bottom: var(--select-option-selected-hover-border-bottom, var(--select-option-selected-border-bottom, var(--select-option-border-bottom, none)));
1539
+ box-shadow: var(--select-option-selected-hover-shadow, var(--select-option-selected-shadow, var(--select-option-shadow, none)));
1540
+ transform: var(--select-option-selected-hover-transform, var(--select-option-selected-transform, var(--select-option-transform, none)));
1514
1541
  }
1515
1542
 
1516
1543
  .option-container.active {
@@ -1818,6 +1845,16 @@ if (!customElements.get('select-option')) {
1818
1845
  * server-side selection, and full customization
1819
1846
  */
1820
1847
  class EnhancedSelect extends HTMLElement {
1848
+ get classMap() {
1849
+ return this._classMap;
1850
+ }
1851
+ set classMap(map) {
1852
+ this._classMap = map;
1853
+ this._setGlobalStylesMirroring(Boolean(this._optionRenderer || map));
1854
+ if (!this.isConnected)
1855
+ return;
1856
+ this._renderOptions();
1857
+ }
1821
1858
  constructor() {
1822
1859
  super();
1823
1860
  this._pageCache = {};
@@ -1861,6 +1898,7 @@ class EnhancedSelect extends HTMLElement {
1861
1898
  this._inputContainer = this._createInputContainer();
1862
1899
  this._input = this._createInput();
1863
1900
  this._arrowContainer = this._createArrowContainer();
1901
+ this._clearControl = this._createClearControl();
1864
1902
  this._dropdown = this._createDropdown();
1865
1903
  this._optionsContainer = this._createOptionsContainer();
1866
1904
  this._liveRegion = this._createLiveRegion();
@@ -2074,8 +2112,25 @@ class EnhancedSelect extends HTMLElement {
2074
2112
  `;
2075
2113
  return container;
2076
2114
  }
2115
+ _createClearControl() {
2116
+ const button = document.createElement('button');
2117
+ button.type = 'button';
2118
+ button.className = 'clear-control-button';
2119
+ button.setAttribute('part', 'clear-button');
2120
+ const icon = document.createElement('span');
2121
+ icon.className = 'clear-control-icon';
2122
+ icon.setAttribute('part', 'clear-icon');
2123
+ icon.textContent = this._config.clearControl.icon || '×';
2124
+ button.setAttribute('aria-label', this._config.clearControl.ariaLabel || 'Clear selection and search');
2125
+ button.appendChild(icon);
2126
+ this._clearControlIcon = icon;
2127
+ return button;
2128
+ }
2077
2129
  _assembleDOM() {
2078
2130
  this._inputContainer.appendChild(this._input);
2131
+ if (this._clearControl) {
2132
+ this._inputContainer.appendChild(this._clearControl);
2133
+ }
2079
2134
  if (this._arrowContainer) {
2080
2135
  this._inputContainer.appendChild(this._arrowContainer);
2081
2136
  }
@@ -2091,6 +2146,7 @@ class EnhancedSelect extends HTMLElement {
2091
2146
  this._dropdown.id = listboxId;
2092
2147
  this._input.setAttribute('aria-controls', listboxId);
2093
2148
  this._input.setAttribute('aria-owns', listboxId);
2149
+ this._syncClearControlState();
2094
2150
  }
2095
2151
  _initializeStyles() {
2096
2152
  const style = document.createElement('style');
@@ -2164,6 +2220,58 @@ class EnhancedSelect extends HTMLElement {
2164
2220
  border-radius: var(--select-arrow-border-radius, 0 4px 4px 0);
2165
2221
  z-index: 2;
2166
2222
  }
2223
+
2224
+ .input-container.has-clear-control {
2225
+ padding: var(--select-input-padding-with-clear, 6px 84px 6px 8px);
2226
+ }
2227
+
2228
+ .input-container.has-clear-control::after {
2229
+ right: var(--select-separator-position-with-clear, 72px);
2230
+ }
2231
+
2232
+ .dropdown-arrow-container.with-clear-control {
2233
+ right: var(--select-arrow-right-with-clear, 32px);
2234
+ }
2235
+
2236
+ .clear-control-button {
2237
+ position: absolute;
2238
+ top: 50%;
2239
+ right: var(--select-clear-button-right, 6px);
2240
+ transform: translateY(-50%);
2241
+ width: var(--select-clear-button-size, 24px);
2242
+ height: var(--select-clear-button-size, 24px);
2243
+ border: var(--select-clear-button-border, none);
2244
+ border-radius: var(--select-clear-button-radius, 999px);
2245
+ background: var(--select-clear-button-bg, transparent);
2246
+ color: var(--select-clear-button-color, #6b7280);
2247
+ display: inline-flex;
2248
+ align-items: center;
2249
+ justify-content: center;
2250
+ cursor: pointer;
2251
+ z-index: 3;
2252
+ transition: var(--select-clear-button-transition, all 0.2s ease);
2253
+ }
2254
+
2255
+ .clear-control-button:hover {
2256
+ background: var(--select-clear-button-hover-bg, rgba(0, 0, 0, 0.06));
2257
+ color: var(--select-clear-button-hover-color, #111827);
2258
+ }
2259
+
2260
+ .clear-control-button:focus-visible {
2261
+ outline: var(--select-clear-button-focus-outline, 2px solid rgba(102, 126, 234, 0.55));
2262
+ outline-offset: 1px;
2263
+ }
2264
+
2265
+ .clear-control-button[hidden] {
2266
+ display: none;
2267
+ }
2268
+
2269
+ .clear-control-icon {
2270
+ font-size: var(--select-clear-icon-size, 16px);
2271
+ line-height: 1;
2272
+ font-weight: var(--select-clear-icon-weight, 500);
2273
+ pointer-events: none;
2274
+ }
2167
2275
 
2168
2276
  .dropdown-arrow-container:hover {
2169
2277
  background-color: var(--select-arrow-hover-bg, rgba(102, 126, 234, 0.08));
@@ -2291,6 +2399,9 @@ class EnhancedSelect extends HTMLElement {
2291
2399
  line-height: var(--select-option-line-height, 1.5);
2292
2400
  border: var(--select-option-border, none);
2293
2401
  border-bottom: var(--select-option-border-bottom, none);
2402
+ border-radius: var(--select-option-border-radius, 0);
2403
+ box-shadow: var(--select-option-shadow, none);
2404
+ transform: var(--select-option-transform, none);
2294
2405
  }
2295
2406
 
2296
2407
  .option:hover {
@@ -2302,18 +2413,47 @@ class EnhancedSelect extends HTMLElement {
2302
2413
  background-color: var(--select-option-selected-bg, #e0e7ff);
2303
2414
  color: var(--select-option-selected-color, #4338ca);
2304
2415
  font-weight: var(--select-option-selected-weight, 500);
2416
+ border: var(--select-option-selected-border, var(--select-option-border, none));
2417
+ border-bottom: var(--select-option-selected-border-bottom, var(--select-option-border-bottom, none));
2418
+ border-radius: var(--select-option-selected-border-radius, var(--select-option-border-radius, 0));
2419
+ box-shadow: var(--select-option-selected-shadow, var(--select-option-shadow, none));
2420
+ transform: var(--select-option-selected-transform, var(--select-option-transform, none));
2421
+ }
2422
+
2423
+ .option.selected:hover {
2424
+ background-color: var(--select-option-selected-hover-bg, var(--select-option-selected-bg, #e0e7ff));
2425
+ color: var(--select-option-selected-hover-color, var(--select-option-selected-color, #4338ca));
2426
+ border: var(--select-option-selected-hover-border, var(--select-option-selected-border, var(--select-option-border, none)));
2427
+ border-bottom: var(--select-option-selected-hover-border-bottom, var(--select-option-selected-border-bottom, var(--select-option-border-bottom, none)));
2428
+ box-shadow: var(--select-option-selected-hover-shadow, var(--select-option-selected-shadow, var(--select-option-shadow, none)));
2429
+ transform: var(--select-option-selected-hover-transform, var(--select-option-selected-transform, var(--select-option-transform, none)));
2305
2430
  }
2306
2431
 
2307
- .option.active {
2432
+ .option.active:not(.selected) {
2308
2433
  background-color: var(--select-option-active-bg, #f3f4f6);
2309
2434
  color: var(--select-option-active-color, #1f2937);
2310
2435
  outline: var(--select-option-active-outline, 2px solid rgba(99, 102, 241, 0.45));
2311
2436
  outline-offset: -2px;
2312
2437
  }
2313
2438
 
2314
- .option:active {
2439
+ .option.selected.active {
2440
+ background-color: var(--select-option-selected-active-bg, var(--select-option-selected-bg, #e0e7ff));
2441
+ color: var(--select-option-selected-active-color, var(--select-option-selected-color, #4338ca));
2442
+ border: var(--select-option-selected-active-border, var(--select-option-selected-border, var(--select-option-border, none)));
2443
+ border-bottom: var(--select-option-selected-active-border-bottom, var(--select-option-selected-border-bottom, var(--select-option-border-bottom, none)));
2444
+ box-shadow: var(--select-option-selected-active-shadow, var(--select-option-selected-shadow, var(--select-option-shadow, none)));
2445
+ transform: var(--select-option-selected-active-transform, var(--select-option-selected-transform, var(--select-option-transform, none)));
2446
+ outline: var(--select-option-selected-active-outline, var(--select-option-active-outline, 2px solid rgba(99, 102, 241, 0.45)));
2447
+ outline-offset: -2px;
2448
+ }
2449
+
2450
+ .option:active:not(.selected) {
2315
2451
  background-color: var(--select-option-pressed-bg, #e5e7eb);
2316
2452
  }
2453
+
2454
+ .option.selected:active {
2455
+ background-color: var(--select-option-selected-pressed-bg, var(--select-option-selected-hover-bg, var(--select-option-selected-bg, #e0e7ff)));
2456
+ }
2317
2457
 
2318
2458
  .load-more-container {
2319
2459
  padding: var(--select-load-more-padding, 12px);
@@ -2459,14 +2599,38 @@ class EnhancedSelect extends HTMLElement {
2459
2599
  .option.selected {
2460
2600
  background-color: var(--select-dark-option-selected-bg, #3730a3);
2461
2601
  color: var(--select-dark-option-selected-text, #e0e7ff);
2602
+ border: var(--select-dark-option-selected-border, var(--select-option-selected-border, var(--select-option-border, none)));
2603
+ border-bottom: var(--select-dark-option-selected-border-bottom, var(--select-option-selected-border-bottom, var(--select-option-border-bottom, none)));
2604
+ box-shadow: var(--select-dark-option-selected-shadow, var(--select-option-selected-shadow, var(--select-option-shadow, none)));
2605
+ transform: var(--select-dark-option-selected-transform, var(--select-option-selected-transform, var(--select-option-transform, none)));
2606
+ }
2607
+
2608
+ .option.selected:hover {
2609
+ background-color: var(--select-dark-option-selected-hover-bg, var(--select-dark-option-selected-bg, #3730a3));
2610
+ color: var(--select-dark-option-selected-hover-color, var(--select-dark-option-selected-text, #e0e7ff));
2611
+ 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)))));
2612
+ 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)))));
2613
+ 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)))));
2614
+ 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)))));
2462
2615
  }
2463
2616
 
2464
- .option.active {
2617
+ .option.active:not(.selected) {
2465
2618
  background-color: var(--select-dark-option-active-bg, #374151);
2466
2619
  color: var(--select-dark-option-active-color, #f9fafb);
2467
2620
  outline: var(--select-dark-option-active-outline, 2px solid rgba(129, 140, 248, 0.55));
2468
2621
  }
2469
2622
 
2623
+ .option.selected.active {
2624
+ background-color: var(--select-dark-option-selected-active-bg, var(--select-dark-option-selected-bg, #3730a3));
2625
+ color: var(--select-dark-option-selected-active-color, var(--select-dark-option-selected-text, #e0e7ff));
2626
+ 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)))));
2627
+ 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)))));
2628
+ 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)))));
2629
+ 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)))));
2630
+ 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)))));
2631
+ outline-offset: -2px;
2632
+ }
2633
+
2470
2634
  .selection-badge {
2471
2635
  background: var(--select-dark-badge-bg, #4f46e5);
2472
2636
  color: var(--select-dark-badge-color, #eef2ff);
@@ -2551,6 +2715,17 @@ class EnhancedSelect extends HTMLElement {
2551
2715
  };
2552
2716
  this._arrowContainer.addEventListener('click', this._boundArrowClick);
2553
2717
  }
2718
+ if (this._clearControl) {
2719
+ this._clearControl.addEventListener('pointerdown', (e) => {
2720
+ e.stopPropagation();
2721
+ e.preventDefault();
2722
+ });
2723
+ this._clearControl.addEventListener('click', (e) => {
2724
+ e.stopPropagation();
2725
+ e.preventDefault();
2726
+ this._handleClearControlClick();
2727
+ });
2728
+ }
2554
2729
  // Input container click - focus input and open dropdown
2555
2730
  this._inputContainer.addEventListener('pointerdown', (e) => {
2556
2731
  const target = e.target;
@@ -2558,6 +2733,8 @@ class EnhancedSelect extends HTMLElement {
2558
2733
  return;
2559
2734
  if (target && target.closest('.dropdown-arrow-container'))
2560
2735
  return;
2736
+ if (target && target.closest('.clear-control-button'))
2737
+ return;
2561
2738
  if (!this._state.isOpen) {
2562
2739
  this._handleOpen();
2563
2740
  }
@@ -2770,6 +2947,7 @@ class EnhancedSelect extends HTMLElement {
2770
2947
  }
2771
2948
  _handleSearch(query) {
2772
2949
  this._state.searchQuery = query;
2950
+ this._syncClearControlState();
2773
2951
  if (query.length > 0) {
2774
2952
  this._perfMark('smilodon-search-input-last');
2775
2953
  this._pendingSearchRenderMark = true;
@@ -2947,7 +3125,9 @@ class EnhancedSelect extends HTMLElement {
2947
3125
  option.classList.add('smilodon-option--active');
2948
3126
  option.setAttribute('aria-selected', 'true');
2949
3127
  }
2950
- option.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
3128
+ if (typeof option.scrollIntoView === 'function') {
3129
+ option.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
3130
+ }
2951
3131
  // Announce position for screen readers
2952
3132
  const total = options.length;
2953
3133
  this._announce(`Item ${index + 1} of ${total}`);
@@ -3074,6 +3254,10 @@ class EnhancedSelect extends HTMLElement {
3074
3254
  const item = this._state.loadedItems[index];
3075
3255
  if (!item)
3076
3256
  return;
3257
+ // Keep active/focus styling aligned with the most recently interacted option.
3258
+ // Without this, a previously selected item may retain active classes/styles
3259
+ // after selecting a different option.
3260
+ this._state.activeIndex = index;
3077
3261
  const isCurrentlySelected = this._state.selectedIndices.has(index);
3078
3262
  if (this._config.selection.mode === 'single') {
3079
3263
  // Single select: clear previous and select new
@@ -3198,6 +3382,7 @@ class EnhancedSelect extends HTMLElement {
3198
3382
  this._inputContainer.insertBefore(badge, this._input);
3199
3383
  });
3200
3384
  }
3385
+ this._syncClearControlState();
3201
3386
  }
3202
3387
  _renderOptionsWithAnimation() {
3203
3388
  // Add fade-out animation
@@ -3313,7 +3498,7 @@ class EnhancedSelect extends HTMLElement {
3313
3498
  }
3314
3499
  set optionRenderer(renderer) {
3315
3500
  this._optionRenderer = renderer;
3316
- this._setGlobalStylesMirroring(Boolean(renderer));
3501
+ this._setGlobalStylesMirroring(Boolean(renderer || this._classMap));
3317
3502
  this._renderOptions();
3318
3503
  }
3319
3504
  /**
@@ -3446,6 +3631,21 @@ class EnhancedSelect extends HTMLElement {
3446
3631
  this._renderOptions();
3447
3632
  this._updateInputDisplay();
3448
3633
  this._emitChange();
3634
+ this._syncClearControlState();
3635
+ }
3636
+ /**
3637
+ * Clear search query and restore full option list
3638
+ */
3639
+ clearSearch() {
3640
+ this._state.searchQuery = '';
3641
+ if (this._config.searchable) {
3642
+ this._input.value = '';
3643
+ if (this._state.selectedIndices.size > 0) {
3644
+ this._updateInputDisplay();
3645
+ }
3646
+ }
3647
+ this._renderOptions();
3648
+ this._syncClearControlState();
3449
3649
  }
3450
3650
  /**
3451
3651
  * Open dropdown
@@ -3472,6 +3672,12 @@ class EnhancedSelect extends HTMLElement {
3472
3672
  this._input.placeholder = this._config.placeholder || 'Select an option...';
3473
3673
  }
3474
3674
  }
3675
+ if (this._clearControl) {
3676
+ this._clearControl.setAttribute('aria-label', this._config.clearControl.ariaLabel || 'Clear selection and search');
3677
+ }
3678
+ if (this._clearControlIcon) {
3679
+ this._clearControlIcon.textContent = this._config.clearControl.icon || '×';
3680
+ }
3475
3681
  if (this._dropdown) {
3476
3682
  if (this._config.selection.mode === 'multi') {
3477
3683
  this._dropdown.setAttribute('aria-multiselectable', 'true');
@@ -3482,8 +3688,47 @@ class EnhancedSelect extends HTMLElement {
3482
3688
  }
3483
3689
  // Re-initialize observers in case infinite scroll was enabled/disabled
3484
3690
  this._initializeObservers();
3691
+ this._syncClearControlState();
3485
3692
  this._renderOptions();
3486
3693
  }
3694
+ _handleClearControlClick() {
3695
+ const shouldClearSelection = this._config.clearControl.clearSelection !== false;
3696
+ const shouldClearSearch = this._config.clearControl.clearSearch !== false;
3697
+ const hadSelection = this._state.selectedIndices.size > 0;
3698
+ const hadSearch = this._state.searchQuery.length > 0;
3699
+ if (shouldClearSelection && hadSelection) {
3700
+ this.clear();
3701
+ }
3702
+ if (shouldClearSearch && hadSearch) {
3703
+ this.clearSearch();
3704
+ }
3705
+ this._emit('clear', {
3706
+ clearedSelection: shouldClearSelection && hadSelection,
3707
+ clearedSearch: shouldClearSearch && hadSearch,
3708
+ });
3709
+ this._config.callbacks.onClear?.({
3710
+ clearedSelection: shouldClearSelection && hadSelection,
3711
+ clearedSearch: shouldClearSearch && hadSearch,
3712
+ });
3713
+ this._input.focus();
3714
+ }
3715
+ _syncClearControlState() {
3716
+ if (!this._clearControl || !this._inputContainer || !this._arrowContainer)
3717
+ return;
3718
+ const enabled = this._config.clearControl.enabled === true;
3719
+ const hasSelection = this._state.selectedIndices.size > 0;
3720
+ const hasSearch = this._state.searchQuery.length > 0;
3721
+ const clearSelection = this._config.clearControl.clearSelection !== false;
3722
+ const clearSearch = this._config.clearControl.clearSearch !== false;
3723
+ const hasSomethingToClear = (clearSelection && hasSelection) || (clearSearch && hasSearch);
3724
+ const hideWhenEmpty = this._config.clearControl.hideWhenEmpty !== false;
3725
+ const visible = enabled && (!hideWhenEmpty || hasSomethingToClear);
3726
+ this._inputContainer.classList.toggle('has-clear-control', enabled);
3727
+ this._arrowContainer.classList.toggle('with-clear-control', enabled);
3728
+ this._clearControl.hidden = !visible;
3729
+ this._clearControl.disabled = !hasSomethingToClear;
3730
+ this._clearControl.setAttribute('aria-hidden', String(!visible));
3731
+ }
3487
3732
  /**
3488
3733
  * Set error state
3489
3734
  */
@@ -4771,10 +5016,17 @@ const shadowDOMStyles = `
4771
5016
  color: var(--ns-item-selected-color, #0066cc);
4772
5017
  }
4773
5018
 
4774
- .ns-item[data-active="true"] {
5019
+ .ns-item[data-active="true"]:not([aria-selected="true"]) {
4775
5020
  background: var(--ns-item-active-bg, rgba(0, 102, 204, 0.2));
4776
5021
  }
4777
5022
 
5023
+ .ns-item[aria-selected="true"][data-active="true"] {
5024
+ background: var(--ns-item-selected-active-bg, var(--ns-item-selected-bg, rgba(0, 102, 204, 0.1)));
5025
+ color: var(--ns-item-selected-active-color, var(--ns-item-selected-color, #0066cc));
5026
+ outline: var(--ns-item-selected-active-outline, 2px solid #0066cc);
5027
+ outline-offset: -2px;
5028
+ }
5029
+
4778
5030
  .ns-item[aria-disabled="true"] {
4779
5031
  opacity: 0.5;
4780
5032
  cursor: not-allowed;