@smilodon/core 1.4.4 → 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 +25 -0
- package/dist/index.cjs +194 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +194 -5
- 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 +194 -5
- 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 +9 -0
- 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.umd.js
CHANGED
|
@@ -1398,6 +1398,14 @@
|
|
|
1398
1398
|
expandLabel: 'Show more',
|
|
1399
1399
|
collapseLabel: 'Show less',
|
|
1400
1400
|
},
|
|
1401
|
+
clearControl: {
|
|
1402
|
+
enabled: false,
|
|
1403
|
+
clearSelection: true,
|
|
1404
|
+
clearSearch: true,
|
|
1405
|
+
hideWhenEmpty: true,
|
|
1406
|
+
ariaLabel: 'Clear selection and search',
|
|
1407
|
+
icon: '×',
|
|
1408
|
+
},
|
|
1401
1409
|
callbacks: {},
|
|
1402
1410
|
enabled: true,
|
|
1403
1411
|
searchable: false,
|
|
@@ -1894,6 +1902,7 @@
|
|
|
1894
1902
|
this._inputContainer = this._createInputContainer();
|
|
1895
1903
|
this._input = this._createInput();
|
|
1896
1904
|
this._arrowContainer = this._createArrowContainer();
|
|
1905
|
+
this._clearControl = this._createClearControl();
|
|
1897
1906
|
this._dropdown = this._createDropdown();
|
|
1898
1907
|
this._optionsContainer = this._createOptionsContainer();
|
|
1899
1908
|
this._liveRegion = this._createLiveRegion();
|
|
@@ -2107,8 +2116,25 @@
|
|
|
2107
2116
|
`;
|
|
2108
2117
|
return container;
|
|
2109
2118
|
}
|
|
2119
|
+
_createClearControl() {
|
|
2120
|
+
const button = document.createElement('button');
|
|
2121
|
+
button.type = 'button';
|
|
2122
|
+
button.className = 'clear-control-button';
|
|
2123
|
+
button.setAttribute('part', 'clear-button');
|
|
2124
|
+
const icon = document.createElement('span');
|
|
2125
|
+
icon.className = 'clear-control-icon';
|
|
2126
|
+
icon.setAttribute('part', 'clear-icon');
|
|
2127
|
+
icon.textContent = this._config.clearControl.icon || '×';
|
|
2128
|
+
button.setAttribute('aria-label', this._config.clearControl.ariaLabel || 'Clear selection and search');
|
|
2129
|
+
button.appendChild(icon);
|
|
2130
|
+
this._clearControlIcon = icon;
|
|
2131
|
+
return button;
|
|
2132
|
+
}
|
|
2110
2133
|
_assembleDOM() {
|
|
2111
2134
|
this._inputContainer.appendChild(this._input);
|
|
2135
|
+
if (this._clearControl) {
|
|
2136
|
+
this._inputContainer.appendChild(this._clearControl);
|
|
2137
|
+
}
|
|
2112
2138
|
if (this._arrowContainer) {
|
|
2113
2139
|
this._inputContainer.appendChild(this._arrowContainer);
|
|
2114
2140
|
}
|
|
@@ -2124,6 +2150,7 @@
|
|
|
2124
2150
|
this._dropdown.id = listboxId;
|
|
2125
2151
|
this._input.setAttribute('aria-controls', listboxId);
|
|
2126
2152
|
this._input.setAttribute('aria-owns', listboxId);
|
|
2153
|
+
this._syncClearControlState();
|
|
2127
2154
|
}
|
|
2128
2155
|
_initializeStyles() {
|
|
2129
2156
|
const style = document.createElement('style');
|
|
@@ -2197,6 +2224,58 @@
|
|
|
2197
2224
|
border-radius: var(--select-arrow-border-radius, 0 4px 4px 0);
|
|
2198
2225
|
z-index: 2;
|
|
2199
2226
|
}
|
|
2227
|
+
|
|
2228
|
+
.input-container.has-clear-control {
|
|
2229
|
+
padding: var(--select-input-padding-with-clear, 6px 84px 6px 8px);
|
|
2230
|
+
}
|
|
2231
|
+
|
|
2232
|
+
.input-container.has-clear-control::after {
|
|
2233
|
+
right: var(--select-separator-position-with-clear, 72px);
|
|
2234
|
+
}
|
|
2235
|
+
|
|
2236
|
+
.dropdown-arrow-container.with-clear-control {
|
|
2237
|
+
right: var(--select-arrow-right-with-clear, 32px);
|
|
2238
|
+
}
|
|
2239
|
+
|
|
2240
|
+
.clear-control-button {
|
|
2241
|
+
position: absolute;
|
|
2242
|
+
top: 50%;
|
|
2243
|
+
right: var(--select-clear-button-right, 6px);
|
|
2244
|
+
transform: translateY(-50%);
|
|
2245
|
+
width: var(--select-clear-button-size, 24px);
|
|
2246
|
+
height: var(--select-clear-button-size, 24px);
|
|
2247
|
+
border: var(--select-clear-button-border, none);
|
|
2248
|
+
border-radius: var(--select-clear-button-radius, 999px);
|
|
2249
|
+
background: var(--select-clear-button-bg, transparent);
|
|
2250
|
+
color: var(--select-clear-button-color, #6b7280);
|
|
2251
|
+
display: inline-flex;
|
|
2252
|
+
align-items: center;
|
|
2253
|
+
justify-content: center;
|
|
2254
|
+
cursor: pointer;
|
|
2255
|
+
z-index: 3;
|
|
2256
|
+
transition: var(--select-clear-button-transition, all 0.2s ease);
|
|
2257
|
+
}
|
|
2258
|
+
|
|
2259
|
+
.clear-control-button:hover {
|
|
2260
|
+
background: var(--select-clear-button-hover-bg, rgba(0, 0, 0, 0.06));
|
|
2261
|
+
color: var(--select-clear-button-hover-color, #111827);
|
|
2262
|
+
}
|
|
2263
|
+
|
|
2264
|
+
.clear-control-button:focus-visible {
|
|
2265
|
+
outline: var(--select-clear-button-focus-outline, 2px solid rgba(102, 126, 234, 0.55));
|
|
2266
|
+
outline-offset: 1px;
|
|
2267
|
+
}
|
|
2268
|
+
|
|
2269
|
+
.clear-control-button[hidden] {
|
|
2270
|
+
display: none;
|
|
2271
|
+
}
|
|
2272
|
+
|
|
2273
|
+
.clear-control-icon {
|
|
2274
|
+
font-size: var(--select-clear-icon-size, 16px);
|
|
2275
|
+
line-height: 1;
|
|
2276
|
+
font-weight: var(--select-clear-icon-weight, 500);
|
|
2277
|
+
pointer-events: none;
|
|
2278
|
+
}
|
|
2200
2279
|
|
|
2201
2280
|
.dropdown-arrow-container:hover {
|
|
2202
2281
|
background-color: var(--select-arrow-hover-bg, rgba(102, 126, 234, 0.08));
|
|
@@ -2354,16 +2433,31 @@
|
|
|
2354
2433
|
transform: var(--select-option-selected-hover-transform, var(--select-option-selected-transform, var(--select-option-transform, none)));
|
|
2355
2434
|
}
|
|
2356
2435
|
|
|
2357
|
-
.option.active {
|
|
2436
|
+
.option.active:not(.selected) {
|
|
2358
2437
|
background-color: var(--select-option-active-bg, #f3f4f6);
|
|
2359
2438
|
color: var(--select-option-active-color, #1f2937);
|
|
2360
2439
|
outline: var(--select-option-active-outline, 2px solid rgba(99, 102, 241, 0.45));
|
|
2361
2440
|
outline-offset: -2px;
|
|
2362
2441
|
}
|
|
2363
2442
|
|
|
2364
|
-
.option
|
|
2443
|
+
.option.selected.active {
|
|
2444
|
+
background-color: var(--select-option-selected-active-bg, var(--select-option-selected-bg, #e0e7ff));
|
|
2445
|
+
color: var(--select-option-selected-active-color, var(--select-option-selected-color, #4338ca));
|
|
2446
|
+
border: var(--select-option-selected-active-border, var(--select-option-selected-border, var(--select-option-border, none)));
|
|
2447
|
+
border-bottom: var(--select-option-selected-active-border-bottom, var(--select-option-selected-border-bottom, var(--select-option-border-bottom, none)));
|
|
2448
|
+
box-shadow: var(--select-option-selected-active-shadow, var(--select-option-selected-shadow, var(--select-option-shadow, none)));
|
|
2449
|
+
transform: var(--select-option-selected-active-transform, var(--select-option-selected-transform, var(--select-option-transform, none)));
|
|
2450
|
+
outline: var(--select-option-selected-active-outline, var(--select-option-active-outline, 2px solid rgba(99, 102, 241, 0.45)));
|
|
2451
|
+
outline-offset: -2px;
|
|
2452
|
+
}
|
|
2453
|
+
|
|
2454
|
+
.option:active:not(.selected) {
|
|
2365
2455
|
background-color: var(--select-option-pressed-bg, #e5e7eb);
|
|
2366
2456
|
}
|
|
2457
|
+
|
|
2458
|
+
.option.selected:active {
|
|
2459
|
+
background-color: var(--select-option-selected-pressed-bg, var(--select-option-selected-hover-bg, var(--select-option-selected-bg, #e0e7ff)));
|
|
2460
|
+
}
|
|
2367
2461
|
|
|
2368
2462
|
.load-more-container {
|
|
2369
2463
|
padding: var(--select-load-more-padding, 12px);
|
|
@@ -2524,12 +2618,23 @@
|
|
|
2524
2618
|
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)))));
|
|
2525
2619
|
}
|
|
2526
2620
|
|
|
2527
|
-
.option.active {
|
|
2621
|
+
.option.active:not(.selected) {
|
|
2528
2622
|
background-color: var(--select-dark-option-active-bg, #374151);
|
|
2529
2623
|
color: var(--select-dark-option-active-color, #f9fafb);
|
|
2530
2624
|
outline: var(--select-dark-option-active-outline, 2px solid rgba(129, 140, 248, 0.55));
|
|
2531
2625
|
}
|
|
2532
2626
|
|
|
2627
|
+
.option.selected.active {
|
|
2628
|
+
background-color: var(--select-dark-option-selected-active-bg, var(--select-dark-option-selected-bg, #3730a3));
|
|
2629
|
+
color: var(--select-dark-option-selected-active-color, var(--select-dark-option-selected-text, #e0e7ff));
|
|
2630
|
+
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)))));
|
|
2631
|
+
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)))));
|
|
2632
|
+
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)))));
|
|
2633
|
+
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)))));
|
|
2634
|
+
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)))));
|
|
2635
|
+
outline-offset: -2px;
|
|
2636
|
+
}
|
|
2637
|
+
|
|
2533
2638
|
.selection-badge {
|
|
2534
2639
|
background: var(--select-dark-badge-bg, #4f46e5);
|
|
2535
2640
|
color: var(--select-dark-badge-color, #eef2ff);
|
|
@@ -2614,6 +2719,17 @@
|
|
|
2614
2719
|
};
|
|
2615
2720
|
this._arrowContainer.addEventListener('click', this._boundArrowClick);
|
|
2616
2721
|
}
|
|
2722
|
+
if (this._clearControl) {
|
|
2723
|
+
this._clearControl.addEventListener('pointerdown', (e) => {
|
|
2724
|
+
e.stopPropagation();
|
|
2725
|
+
e.preventDefault();
|
|
2726
|
+
});
|
|
2727
|
+
this._clearControl.addEventListener('click', (e) => {
|
|
2728
|
+
e.stopPropagation();
|
|
2729
|
+
e.preventDefault();
|
|
2730
|
+
this._handleClearControlClick();
|
|
2731
|
+
});
|
|
2732
|
+
}
|
|
2617
2733
|
// Input container click - focus input and open dropdown
|
|
2618
2734
|
this._inputContainer.addEventListener('pointerdown', (e) => {
|
|
2619
2735
|
const target = e.target;
|
|
@@ -2621,6 +2737,8 @@
|
|
|
2621
2737
|
return;
|
|
2622
2738
|
if (target && target.closest('.dropdown-arrow-container'))
|
|
2623
2739
|
return;
|
|
2740
|
+
if (target && target.closest('.clear-control-button'))
|
|
2741
|
+
return;
|
|
2624
2742
|
if (!this._state.isOpen) {
|
|
2625
2743
|
this._handleOpen();
|
|
2626
2744
|
}
|
|
@@ -2833,6 +2951,7 @@
|
|
|
2833
2951
|
}
|
|
2834
2952
|
_handleSearch(query) {
|
|
2835
2953
|
this._state.searchQuery = query;
|
|
2954
|
+
this._syncClearControlState();
|
|
2836
2955
|
if (query.length > 0) {
|
|
2837
2956
|
this._perfMark('smilodon-search-input-last');
|
|
2838
2957
|
this._pendingSearchRenderMark = true;
|
|
@@ -3010,7 +3129,9 @@
|
|
|
3010
3129
|
option.classList.add('smilodon-option--active');
|
|
3011
3130
|
option.setAttribute('aria-selected', 'true');
|
|
3012
3131
|
}
|
|
3013
|
-
option.scrollIntoView
|
|
3132
|
+
if (typeof option.scrollIntoView === 'function') {
|
|
3133
|
+
option.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
|
|
3134
|
+
}
|
|
3014
3135
|
// Announce position for screen readers
|
|
3015
3136
|
const total = options.length;
|
|
3016
3137
|
this._announce(`Item ${index + 1} of ${total}`);
|
|
@@ -3265,6 +3386,7 @@
|
|
|
3265
3386
|
this._inputContainer.insertBefore(badge, this._input);
|
|
3266
3387
|
});
|
|
3267
3388
|
}
|
|
3389
|
+
this._syncClearControlState();
|
|
3268
3390
|
}
|
|
3269
3391
|
_renderOptionsWithAnimation() {
|
|
3270
3392
|
// Add fade-out animation
|
|
@@ -3513,6 +3635,21 @@
|
|
|
3513
3635
|
this._renderOptions();
|
|
3514
3636
|
this._updateInputDisplay();
|
|
3515
3637
|
this._emitChange();
|
|
3638
|
+
this._syncClearControlState();
|
|
3639
|
+
}
|
|
3640
|
+
/**
|
|
3641
|
+
* Clear search query and restore full option list
|
|
3642
|
+
*/
|
|
3643
|
+
clearSearch() {
|
|
3644
|
+
this._state.searchQuery = '';
|
|
3645
|
+
if (this._config.searchable) {
|
|
3646
|
+
this._input.value = '';
|
|
3647
|
+
if (this._state.selectedIndices.size > 0) {
|
|
3648
|
+
this._updateInputDisplay();
|
|
3649
|
+
}
|
|
3650
|
+
}
|
|
3651
|
+
this._renderOptions();
|
|
3652
|
+
this._syncClearControlState();
|
|
3516
3653
|
}
|
|
3517
3654
|
/**
|
|
3518
3655
|
* Open dropdown
|
|
@@ -3539,6 +3676,12 @@
|
|
|
3539
3676
|
this._input.placeholder = this._config.placeholder || 'Select an option...';
|
|
3540
3677
|
}
|
|
3541
3678
|
}
|
|
3679
|
+
if (this._clearControl) {
|
|
3680
|
+
this._clearControl.setAttribute('aria-label', this._config.clearControl.ariaLabel || 'Clear selection and search');
|
|
3681
|
+
}
|
|
3682
|
+
if (this._clearControlIcon) {
|
|
3683
|
+
this._clearControlIcon.textContent = this._config.clearControl.icon || '×';
|
|
3684
|
+
}
|
|
3542
3685
|
if (this._dropdown) {
|
|
3543
3686
|
if (this._config.selection.mode === 'multi') {
|
|
3544
3687
|
this._dropdown.setAttribute('aria-multiselectable', 'true');
|
|
@@ -3549,8 +3692,47 @@
|
|
|
3549
3692
|
}
|
|
3550
3693
|
// Re-initialize observers in case infinite scroll was enabled/disabled
|
|
3551
3694
|
this._initializeObservers();
|
|
3695
|
+
this._syncClearControlState();
|
|
3552
3696
|
this._renderOptions();
|
|
3553
3697
|
}
|
|
3698
|
+
_handleClearControlClick() {
|
|
3699
|
+
const shouldClearSelection = this._config.clearControl.clearSelection !== false;
|
|
3700
|
+
const shouldClearSearch = this._config.clearControl.clearSearch !== false;
|
|
3701
|
+
const hadSelection = this._state.selectedIndices.size > 0;
|
|
3702
|
+
const hadSearch = this._state.searchQuery.length > 0;
|
|
3703
|
+
if (shouldClearSelection && hadSelection) {
|
|
3704
|
+
this.clear();
|
|
3705
|
+
}
|
|
3706
|
+
if (shouldClearSearch && hadSearch) {
|
|
3707
|
+
this.clearSearch();
|
|
3708
|
+
}
|
|
3709
|
+
this._emit('clear', {
|
|
3710
|
+
clearedSelection: shouldClearSelection && hadSelection,
|
|
3711
|
+
clearedSearch: shouldClearSearch && hadSearch,
|
|
3712
|
+
});
|
|
3713
|
+
this._config.callbacks.onClear?.({
|
|
3714
|
+
clearedSelection: shouldClearSelection && hadSelection,
|
|
3715
|
+
clearedSearch: shouldClearSearch && hadSearch,
|
|
3716
|
+
});
|
|
3717
|
+
this._input.focus();
|
|
3718
|
+
}
|
|
3719
|
+
_syncClearControlState() {
|
|
3720
|
+
if (!this._clearControl || !this._inputContainer || !this._arrowContainer)
|
|
3721
|
+
return;
|
|
3722
|
+
const enabled = this._config.clearControl.enabled === true;
|
|
3723
|
+
const hasSelection = this._state.selectedIndices.size > 0;
|
|
3724
|
+
const hasSearch = this._state.searchQuery.length > 0;
|
|
3725
|
+
const clearSelection = this._config.clearControl.clearSelection !== false;
|
|
3726
|
+
const clearSearch = this._config.clearControl.clearSearch !== false;
|
|
3727
|
+
const hasSomethingToClear = (clearSelection && hasSelection) || (clearSearch && hasSearch);
|
|
3728
|
+
const hideWhenEmpty = this._config.clearControl.hideWhenEmpty !== false;
|
|
3729
|
+
const visible = enabled && (!hideWhenEmpty || hasSomethingToClear);
|
|
3730
|
+
this._inputContainer.classList.toggle('has-clear-control', enabled);
|
|
3731
|
+
this._arrowContainer.classList.toggle('with-clear-control', enabled);
|
|
3732
|
+
this._clearControl.hidden = !visible;
|
|
3733
|
+
this._clearControl.disabled = !hasSomethingToClear;
|
|
3734
|
+
this._clearControl.setAttribute('aria-hidden', String(!visible));
|
|
3735
|
+
}
|
|
3554
3736
|
/**
|
|
3555
3737
|
* Set error state
|
|
3556
3738
|
*/
|
|
@@ -4838,10 +5020,17 @@
|
|
|
4838
5020
|
color: var(--ns-item-selected-color, #0066cc);
|
|
4839
5021
|
}
|
|
4840
5022
|
|
|
4841
|
-
.ns-item[data-active="true"] {
|
|
5023
|
+
.ns-item[data-active="true"]:not([aria-selected="true"]) {
|
|
4842
5024
|
background: var(--ns-item-active-bg, rgba(0, 102, 204, 0.2));
|
|
4843
5025
|
}
|
|
4844
5026
|
|
|
5027
|
+
.ns-item[aria-selected="true"][data-active="true"] {
|
|
5028
|
+
background: var(--ns-item-selected-active-bg, var(--ns-item-selected-bg, rgba(0, 102, 204, 0.1)));
|
|
5029
|
+
color: var(--ns-item-selected-active-color, var(--ns-item-selected-color, #0066cc));
|
|
5030
|
+
outline: var(--ns-item-selected-active-outline, 2px solid #0066cc);
|
|
5031
|
+
outline-offset: -2px;
|
|
5032
|
+
}
|
|
5033
|
+
|
|
4845
5034
|
.ns-item[aria-disabled="true"] {
|
|
4846
5035
|
opacity: 0.5;
|
|
4847
5036
|
cursor: not-allowed;
|