diff --git a/.changeset/dirty-laws-trade.md b/.changeset/dirty-laws-trade.md new file mode 100644 index 0000000000..1bb710773e --- /dev/null +++ b/.changeset/dirty-laws-trade.md @@ -0,0 +1,5 @@ +--- +"react-select": minor +--- + +Now pass the focusedOption to the MenuList Component as a prop diff --git a/.changeset/fair-panthers-marry.md b/.changeset/fair-panthers-marry.md new file mode 100644 index 0000000000..3a2fa9c028 --- /dev/null +++ b/.changeset/fair-panthers-marry.md @@ -0,0 +1,5 @@ +--- +"react-select": patch +--- + +The Menu bottom is no longer scrolled into view when menuShouldScrollIntoView=false diff --git a/docs/App/Header.js b/docs/App/Header.js index c5ac2bc791..a729cd6d04 100644 --- a/docs/App/Header.js +++ b/docs/App/Header.js @@ -106,24 +106,17 @@ const Container = props => ( ); type HeaderProps = RouterProps & { children: Node }; -type HeaderState = { contentHeight: 'auto' | number, stars: number }; +type HeaderState = { stars: number }; const apiUrl = 'https://api.github.com/repos/jedwatson/react-select'; class Header extends Component { nav: HTMLElement; content: HTMLElement; - state = { contentHeight: 'auto', stars: 0 }; + state = { stars: 0 }; componentDidMount() { this.getStarCount(); } - UNSAFE_componentWillReceiveProps({ location }: HeaderProps) { - const valid = ['/', '/home']; - const shouldCollapse = !valid.includes(this.props.location.pathname); - if (location.pathname !== this.props.location.pathname && shouldCollapse) { - this.toggleCollapse(); - } - } getStarCount = () => { fetch(apiUrl) .then(res => res.json()) @@ -139,25 +132,28 @@ class Header extends Component { const valid = ['/', '/home']; return valid.includes(props.location.pathname); }; - toggleCollapse = () => { - const contentHeight = this.content.scrollHeight; - this.setState({ contentHeight }); - }; - getContent = ref => { + setContentRef = ref => { if (!ref) return; this.content = ref; }; + getContentHeight = () => { + if (!this.content) { + return 'auto'; + } + + return this.content.scrollHeight; + }; render() { const { children, history } = this.props; - const { contentHeight, stars } = this.state; + const { stars } = this.state; return ( {children}

{ }} isLoading={isLoading} maxHeight={maxHeight} + focusedOption={focusedOption} > {menuUI} diff --git a/packages/react-select/src/components/Menu.js b/packages/react-select/src/components/Menu.js index 605b8a79f4..0ebb3fd64a 100644 --- a/packages/react-select/src/components/Menu.js +++ b/packages/react-select/src/components/Menu.js @@ -23,6 +23,7 @@ import type { MenuPlacement, MenuPosition, CommonProps, + OptionType, } from '../types'; import type { Theme } from '../types'; @@ -145,7 +146,9 @@ export function getMenuPlacement({ // BOTTOM: allow browser to increase scrollable area and immediately set scroll if (placement === 'bottom') { - scrollTo(scrollParent, scrollDown); + if (shouldScroll) { + scrollTo(scrollParent, scrollDown); + } return { placement: 'bottom', maxHeight }; } break; @@ -350,6 +353,8 @@ export type MenuListProps = { children: Node, /** Inner ref to DOM Node */ innerRef: InnerRef, + /** The currently focused option */ + focusedOption: OptionType, /** Props to be passed to the menu-list wrapper. */ innerProps: {}, }; diff --git a/packages/react-select/src/utils.js b/packages/react-select/src/utils.js index 4a74c837b2..4564866a02 100644 --- a/packages/react-select/src/utils.js +++ b/packages/react-select/src/utils.js @@ -306,10 +306,11 @@ const options = { return (passiveOptionAccessed = true); }, }; - -if (document.addEventListener && document.removeEventListener) { - document.addEventListener('p', noop, options); - document.removeEventListener('p', noop, false); +// check for SSR +const w = typeof window !== 'undefined' ? window : {}; +if (w.addEventListener && w.removeEventListener) { + w.addEventListener('p', noop, options); + w.removeEventListener('p', noop, false); } export const supportsPassiveEvents: boolean = passiveOptionAccessed;