@smilodon/core 1.0.6 → 1.0.8

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.umd.js CHANGED
@@ -1563,8 +1563,13 @@
1563
1563
  this._config.callbacks.onOpen?.();
1564
1564
  // Scroll to selected if configured
1565
1565
  if (this._config.scrollToSelected.enabled) {
1566
- // Use setTimeout to allow render to complete
1567
- setTimeout(() => this._scrollToSelected(), 0);
1566
+ // Use requestAnimationFrame for better timing after render
1567
+ requestAnimationFrame(() => {
1568
+ // Double RAF to ensure layout is complete
1569
+ requestAnimationFrame(() => {
1570
+ this._scrollToSelected();
1571
+ });
1572
+ });
1568
1573
  }
1569
1574
  }
1570
1575
  _handleClose() {
@@ -1914,26 +1919,44 @@
1914
1919
  return;
1915
1920
  const target = this._config.scrollToSelected.multiSelectTarget;
1916
1921
  const indices = Array.from(this._state.selectedIndices).sort((a, b) => a - b);
1917
- const targetIndex = target === 'first' ? indices[0] : indices[indices.length - 1];
1918
- // FIX: Find the option element by ID instead of index in children
1919
- // because children list might be filtered or reordered
1922
+ // For multi-select, find the closest selected item to the current scroll position
1923
+ let targetIndex;
1924
+ if (this._config.selection.mode === 'multi' && indices.length > 1) {
1925
+ // Calculate which selected item is closest to the center of the viewport
1926
+ const dropdownRect = this._dropdown.getBoundingClientRect();
1927
+ const viewportCenter = this._dropdown.scrollTop + (dropdownRect.height / 2);
1928
+ // Find the selected item closest to viewport center
1929
+ let closestIndex = indices[0];
1930
+ let closestDistance = Infinity;
1931
+ for (const index of indices) {
1932
+ const optionId = `${this._uniqueId}-option-${index}`;
1933
+ const option = this._optionsContainer.querySelector(`[id="${optionId}"]`);
1934
+ if (option) {
1935
+ const optionTop = option.offsetTop;
1936
+ const distance = Math.abs(optionTop - viewportCenter);
1937
+ if (distance < closestDistance) {
1938
+ closestDistance = distance;
1939
+ closestIndex = index;
1940
+ }
1941
+ }
1942
+ }
1943
+ targetIndex = closestIndex;
1944
+ }
1945
+ else {
1946
+ // For single select or only one selected item, use the configured target
1947
+ targetIndex = target === 'first' ? indices[0] : indices[indices.length - 1];
1948
+ }
1949
+ // Find and scroll to the target option
1920
1950
  const optionId = `${this._uniqueId}-option-${targetIndex}`;
1921
- // We need to search in shadow root or options container
1922
- // Since options are custom elements, we can find them by ID if we set it (we do)
1923
- // But wait, we set ID on the element instance, but is it in the DOM?
1924
- // If filtered out, it won't be in the DOM.
1925
- // If we are searching, we might not want to scroll to selected if it's not visible
1926
- // But if we just opened the dropdown, we usually want to see the selected item.
1927
- // If the selected item is filtered out, we can't scroll to it.
1928
- // Try to find the element in the options container
1929
- // Note: querySelector on shadowRoot works if we set the ID attribute
1930
- // In _renderOptions we set: option.id = ...
1931
1951
  const option = this._optionsContainer.querySelector(`[id="${optionId}"]`);
1932
1952
  if (option) {
1953
+ // Use smooth scrolling with center alignment for better UX
1933
1954
  option.scrollIntoView({
1934
1955
  block: this._config.scrollToSelected.block || 'center',
1935
1956
  behavior: 'smooth',
1936
1957
  });
1958
+ // Also set it as active for keyboard navigation
1959
+ this._setActive(targetIndex);
1937
1960
  }
1938
1961
  }
1939
1962
  async _loadMoreItems() {