mirror of
https://github.com/maputnik/editor.git
synced 2026-08-25 22:47:39 +00:00
Fix autocomplete dropdown height
This commit is contained in:
@@ -15,7 +15,6 @@
|
|||||||
- Remove react-autobind dependency
|
- Remove react-autobind dependency
|
||||||
- Remove usage of legacy `childContextTypes` API
|
- Remove usage of legacy `childContextTypes` API
|
||||||
- Replace react-autocomplete with Downshift in the autocomplete component
|
- Replace react-autocomplete with Downshift in the autocomplete component
|
||||||
- Simplify autocomplete component and fix dropdown flicker when clicking
|
|
||||||
- _...Add new stuff here..._
|
- _...Add new stuff here..._
|
||||||
|
|
||||||
### 🐞 Bug fixes
|
### 🐞 Bug fixes
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ import React from 'react'
|
|||||||
import classnames from 'classnames'
|
import classnames from 'classnames'
|
||||||
import {useCombobox} from 'downshift'
|
import {useCombobox} from 'downshift'
|
||||||
|
|
||||||
|
const MAX_HEIGHT = 140
|
||||||
|
|
||||||
export type InputAutocompleteProps = {
|
export type InputAutocompleteProps = {
|
||||||
value?: string
|
value?: string
|
||||||
options?: any[]
|
options?: any[]
|
||||||
@@ -16,12 +18,21 @@ export default function InputAutocomplete({
|
|||||||
'aria-label': ariaLabel,
|
'aria-label': ariaLabel,
|
||||||
}: InputAutocompleteProps) {
|
}: InputAutocompleteProps) {
|
||||||
const [input, setInput] = React.useState(value || '')
|
const [input, setInput] = React.useState(value || '')
|
||||||
|
const menuRef = React.useRef<HTMLDivElement>(null)
|
||||||
|
const [maxHeight, setMaxHeight] = React.useState(MAX_HEIGHT)
|
||||||
|
|
||||||
const filteredItems = React.useMemo(() => {
|
const filteredItems = React.useMemo(() => {
|
||||||
const lv = input.toLowerCase()
|
const lv = input.toLowerCase()
|
||||||
return options.filter((item) => item[0].toLowerCase().includes(lv))
|
return options.filter((item) => item[0].toLowerCase().includes(lv))
|
||||||
}, [options, input])
|
}, [options, input])
|
||||||
|
|
||||||
|
const calcMaxHeight = React.useCallback(() => {
|
||||||
|
if (menuRef.current) {
|
||||||
|
const space = window.innerHeight - menuRef.current.getBoundingClientRect().top
|
||||||
|
setMaxHeight(Math.min(space, MAX_HEIGHT))
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
const {
|
const {
|
||||||
isOpen,
|
isOpen,
|
||||||
getMenuProps,
|
getMenuProps,
|
||||||
@@ -48,10 +59,22 @@ export default function InputAutocomplete({
|
|||||||
if (typeof v === 'string') {
|
if (typeof v === 'string') {
|
||||||
setInput(v)
|
setInput(v)
|
||||||
onChange(v === '' ? undefined : v)
|
onChange(v === '' ? undefined : v)
|
||||||
|
openMenu()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (isOpen) {
|
||||||
|
calcMaxHeight()
|
||||||
|
}
|
||||||
|
}, [isOpen, calcMaxHeight])
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
window.addEventListener('resize', calcMaxHeight)
|
||||||
|
return () => window.removeEventListener('resize', calcMaxHeight)
|
||||||
|
}, [calcMaxHeight])
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
setInput(value || '')
|
setInput(value || '')
|
||||||
}, [value])
|
}, [value])
|
||||||
@@ -67,9 +90,10 @@ export default function InputAutocomplete({
|
|||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
{...getMenuProps({
|
{...getMenuProps({}, {suppressRefError: true})}
|
||||||
className: 'maputnik-autocomplete-menu',
|
ref={menuRef}
|
||||||
})}
|
style={{position: 'fixed', overflow: 'auto', maxHeight, zIndex: 998}}
|
||||||
|
className="maputnik-autocomplete-menu"
|
||||||
>
|
>
|
||||||
{isOpen &&
|
{isOpen &&
|
||||||
filteredItems.map((item, index) => (
|
filteredItems.map((item, index) => (
|
||||||
|
|||||||
Reference in New Issue
Block a user