@smilodon/core 1.0.9 → 1.0.11
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.cjs +94 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +94 -23
- 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 +94 -23
- 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 +2 -0
- package/dist/types/src/config/global-config.d.ts +14 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -865,6 +865,13 @@ const defaultConfig = {
|
|
|
865
865
|
preloadAdjacent: true,
|
|
866
866
|
scrollRestoration: 'auto',
|
|
867
867
|
},
|
|
868
|
+
expandable: {
|
|
869
|
+
enabled: false,
|
|
870
|
+
collapsedHeight: '300px',
|
|
871
|
+
expandedHeight: '500px',
|
|
872
|
+
expandLabel: 'Show more',
|
|
873
|
+
collapseLabel: 'Show less',
|
|
874
|
+
},
|
|
868
875
|
callbacks: {},
|
|
869
876
|
enabled: true,
|
|
870
877
|
searchable: false,
|
|
@@ -975,6 +982,7 @@ class EnhancedSelect extends HTMLElement {
|
|
|
975
982
|
lastScrollPosition: 0,
|
|
976
983
|
lastNotifiedQuery: null,
|
|
977
984
|
lastNotifiedResultCount: 0,
|
|
985
|
+
isExpanded: false,
|
|
978
986
|
};
|
|
979
987
|
// Create DOM structure
|
|
980
988
|
this._container = this._createContainer();
|
|
@@ -1267,17 +1275,39 @@ class EnhancedSelect extends HTMLElement {
|
|
|
1267
1275
|
right: 0;
|
|
1268
1276
|
margin-top: 4px;
|
|
1269
1277
|
max-height: 300px;
|
|
1270
|
-
|
|
1278
|
+
display: flex;
|
|
1279
|
+
flex-direction: column;
|
|
1271
1280
|
background: var(--select-dropdown-bg, white);
|
|
1272
1281
|
border: 1px solid var(--select-dropdown-border, #ccc);
|
|
1273
1282
|
border-radius: var(--select-border-radius, 4px);
|
|
1274
1283
|
box-shadow: var(--select-dropdown-shadow, 0 4px 6px rgba(0,0,0,0.1));
|
|
1275
1284
|
z-index: var(--select-dropdown-z-index, 1000);
|
|
1285
|
+
transition: max-height 0.3s ease-in-out;
|
|
1276
1286
|
}
|
|
1277
1287
|
|
|
1278
1288
|
.options-container {
|
|
1279
1289
|
position: relative;
|
|
1280
1290
|
transition: opacity 0.2s ease-in-out;
|
|
1291
|
+
overflow-y: auto;
|
|
1292
|
+
flex: 1;
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1295
|
+
.expand-toggle {
|
|
1296
|
+
padding: 8px;
|
|
1297
|
+
text-align: center;
|
|
1298
|
+
background: #f9fafb;
|
|
1299
|
+
border-top: 1px solid #e5e7eb;
|
|
1300
|
+
cursor: pointer;
|
|
1301
|
+
font-size: 12px;
|
|
1302
|
+
color: #6b7280;
|
|
1303
|
+
font-weight: 500;
|
|
1304
|
+
transition: background 0.2s;
|
|
1305
|
+
flex-shrink: 0;
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1308
|
+
.expand-toggle:hover {
|
|
1309
|
+
background: #f3f4f6;
|
|
1310
|
+
color: #374151;
|
|
1281
1311
|
}
|
|
1282
1312
|
|
|
1283
1313
|
.option {
|
|
@@ -1540,6 +1570,13 @@ class EnhancedSelect extends HTMLElement {
|
|
|
1540
1570
|
return;
|
|
1541
1571
|
this._state.isOpen = true;
|
|
1542
1572
|
this._dropdown.style.display = 'block';
|
|
1573
|
+
// Set initial height based on expandable config
|
|
1574
|
+
if (this._config.expandable.enabled) {
|
|
1575
|
+
const height = this._state.isExpanded
|
|
1576
|
+
? (this._config.expandable.expandedHeight || '500px')
|
|
1577
|
+
: (this._config.expandable.collapsedHeight || '300px');
|
|
1578
|
+
this._dropdown.style.maxHeight = height;
|
|
1579
|
+
}
|
|
1543
1580
|
this._input.setAttribute('aria-expanded', 'true');
|
|
1544
1581
|
this._updateArrowRotation();
|
|
1545
1582
|
// Clear search query when opening to show all options
|
|
@@ -2264,24 +2301,33 @@ class EnhancedSelect extends HTMLElement {
|
|
|
2264
2301
|
});
|
|
2265
2302
|
this._optionsContainer.appendChild(header);
|
|
2266
2303
|
group.options.forEach(item => {
|
|
2267
|
-
|
|
2304
|
+
// Find original index for correct ID generation and selection
|
|
2305
|
+
const index = this._state.loadedItems.indexOf(item);
|
|
2306
|
+
if (index !== -1) {
|
|
2307
|
+
this._renderSingleOption(item, index, getValue, getLabel);
|
|
2308
|
+
}
|
|
2268
2309
|
});
|
|
2269
2310
|
});
|
|
2270
2311
|
}
|
|
2271
2312
|
else {
|
|
2272
2313
|
// Normal rendering (flat list or filtered)
|
|
2273
|
-
|
|
2274
|
-
|
|
2314
|
+
let hasRenderedItems = false;
|
|
2315
|
+
this._state.loadedItems.forEach((item, index) => {
|
|
2316
|
+
// Apply filter if query exists
|
|
2317
|
+
if (query) {
|
|
2275
2318
|
try {
|
|
2276
2319
|
const label = String(getLabel(item)).toLowerCase();
|
|
2277
|
-
|
|
2320
|
+
if (!label.includes(query))
|
|
2321
|
+
return;
|
|
2278
2322
|
}
|
|
2279
2323
|
catch (e) {
|
|
2280
|
-
return
|
|
2324
|
+
return;
|
|
2281
2325
|
}
|
|
2282
|
-
}
|
|
2283
|
-
|
|
2284
|
-
|
|
2326
|
+
}
|
|
2327
|
+
hasRenderedItems = true;
|
|
2328
|
+
this._renderSingleOption(item, index, getValue, getLabel);
|
|
2329
|
+
});
|
|
2330
|
+
if (!hasRenderedItems && !this._state.isBusy) {
|
|
2285
2331
|
const empty = document.createElement('div');
|
|
2286
2332
|
empty.className = 'empty-state';
|
|
2287
2333
|
if (query) {
|
|
@@ -2292,11 +2338,6 @@ class EnhancedSelect extends HTMLElement {
|
|
|
2292
2338
|
}
|
|
2293
2339
|
this._optionsContainer.appendChild(empty);
|
|
2294
2340
|
}
|
|
2295
|
-
else {
|
|
2296
|
-
itemsToRender.forEach((item) => {
|
|
2297
|
-
this._renderSingleOption(item, getValue, getLabel);
|
|
2298
|
-
});
|
|
2299
|
-
}
|
|
2300
2341
|
}
|
|
2301
2342
|
// Append Busy Indicator if busy
|
|
2302
2343
|
if (this._state.isBusy && this._config.busyBucket.enabled) {
|
|
@@ -2318,27 +2359,57 @@ class EnhancedSelect extends HTMLElement {
|
|
|
2318
2359
|
else if ((this._config.loadMore.enabled || this._config.infiniteScroll.enabled) && this._state.loadedItems.length > 0) {
|
|
2319
2360
|
this._addLoadMoreTrigger();
|
|
2320
2361
|
}
|
|
2362
|
+
// Render Expand Button if enabled
|
|
2363
|
+
if (this._config.expandable.enabled) {
|
|
2364
|
+
this._renderExpandButton();
|
|
2365
|
+
}
|
|
2321
2366
|
}
|
|
2322
|
-
|
|
2367
|
+
_renderExpandButton() {
|
|
2368
|
+
const button = document.createElement('div');
|
|
2369
|
+
button.className = 'expand-toggle';
|
|
2370
|
+
button.textContent = this._state.isExpanded
|
|
2371
|
+
? (this._config.expandable.collapseLabel || 'Show less')
|
|
2372
|
+
: (this._config.expandable.expandLabel || 'Show more');
|
|
2373
|
+
button.addEventListener('click', (e) => {
|
|
2374
|
+
e.stopPropagation(); // Prevent closing dropdown
|
|
2375
|
+
this._toggleExpand();
|
|
2376
|
+
});
|
|
2377
|
+
this._dropdown.appendChild(button);
|
|
2378
|
+
}
|
|
2379
|
+
_toggleExpand() {
|
|
2380
|
+
this._state.isExpanded = !this._state.isExpanded;
|
|
2381
|
+
const height = this._state.isExpanded
|
|
2382
|
+
? (this._config.expandable.expandedHeight || '500px')
|
|
2383
|
+
: (this._config.expandable.collapsedHeight || '300px');
|
|
2384
|
+
this._dropdown.style.maxHeight = height;
|
|
2385
|
+
// Re-render button to update label
|
|
2386
|
+
const existingButton = this._dropdown.querySelector('.expand-toggle');
|
|
2387
|
+
if (existingButton) {
|
|
2388
|
+
existingButton.textContent = this._state.isExpanded
|
|
2389
|
+
? (this._config.expandable.collapseLabel || 'Show less')
|
|
2390
|
+
: (this._config.expandable.expandLabel || 'Show more');
|
|
2391
|
+
}
|
|
2392
|
+
}
|
|
2393
|
+
_renderSingleOption(item, index, getValue, getLabel) {
|
|
2323
2394
|
const option = document.createElement('div');
|
|
2324
2395
|
option.className = 'option';
|
|
2396
|
+
option.id = `${this._uniqueId}-option-${index}`;
|
|
2325
2397
|
const value = getValue(item);
|
|
2326
2398
|
const label = getLabel(item);
|
|
2327
2399
|
option.textContent = label;
|
|
2328
2400
|
option.dataset.value = String(value);
|
|
2401
|
+
option.dataset.index = String(index); // Also useful for debugging/selectors
|
|
2329
2402
|
// Check if selected using selectedItems map
|
|
2330
|
-
const isSelected =
|
|
2331
|
-
const selectedValue = getValue(selectedItem);
|
|
2332
|
-
return selectedValue === value;
|
|
2333
|
-
});
|
|
2403
|
+
const isSelected = this._state.selectedIndices.has(index);
|
|
2334
2404
|
if (isSelected) {
|
|
2335
2405
|
option.classList.add('selected');
|
|
2406
|
+
option.setAttribute('aria-selected', 'true');
|
|
2407
|
+
}
|
|
2408
|
+
else {
|
|
2409
|
+
option.setAttribute('aria-selected', 'false');
|
|
2336
2410
|
}
|
|
2337
2411
|
option.addEventListener('click', () => {
|
|
2338
|
-
|
|
2339
|
-
if (index !== -1) {
|
|
2340
|
-
this._selectOption(index);
|
|
2341
|
-
}
|
|
2412
|
+
this._selectOption(index);
|
|
2342
2413
|
});
|
|
2343
2414
|
this._optionsContainer.appendChild(option);
|
|
2344
2415
|
}
|