diff --git a/.changeset/feat-select-scroll-to-selected.md b/.changeset/feat-select-scroll-to-selected.md new file mode 100644 index 00000000..dbd2a51e --- /dev/null +++ b/.changeset/feat-select-scroll-to-selected.md @@ -0,0 +1,5 @@ +--- +"@tiny-design/react": minor +--- + +Add `scrollToSelected` prop to Select component that automatically scrolls the dropdown to the first selected option when opened diff --git a/packages/react/src/select/__tests__/select.test.tsx b/packages/react/src/select/__tests__/select.test.tsx index 073cf1fd..49f4a302 100644 --- a/packages/react/src/select/__tests__/select.test.tsx +++ b/packages/react/src/select/__tests__/select.test.tsx @@ -1,4 +1,4 @@ -import { render, fireEvent } from '@testing-library/react'; +import { render, fireEvent, act } from '@testing-library/react'; import Select from '../index'; const { Option, OptGroup } = Select; @@ -7,6 +7,14 @@ const { Option, OptGroup } = Select; const getOptions = () => document.querySelectorAll('.ty-select-option'); describe(' @@ -349,6 +357,55 @@ describe('); + const selector = container.querySelector('.ty-select__selector') as HTMLElement; + + // Mock offsetTop on selected option before opening + const origDescriptor = Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'offsetTop'); + Object.defineProperty(HTMLElement.prototype, 'offsetTop', { + configurable: true, + get() { + if (this.getAttribute?.('aria-selected') === 'true') return 400; + return 0; + }, + }); + + fireEvent.click(selector); + jest.runAllTimers(); + + const dropdown = document.querySelector('.ty-select__dropdown') as HTMLElement; + expect(dropdown.scrollTop).toBe(400); + + if (origDescriptor) { + Object.defineProperty(HTMLElement.prototype, 'offsetTop', origDescriptor); + } + }); + + it('should not scroll when scrollToSelected is false', () => { + const options = Array.from({ length: 50 }, (_, i) => ({ + value: `opt-${i}`, + label: `Option ${i}`, + })); + + const { container } = render( + +