Skip to content

Commit

Permalink
[components] Clean up StatelessSearchableSelect hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
mariuslundgard authored and rexxars committed Oct 6, 2020
1 parent 5a804ec commit b46d603
Showing 1 changed file with 77 additions and 56 deletions.
133 changes: 77 additions & 56 deletions packages/@sanity/components/src/selects/StatelessSearchableSelect.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {Modifier} from '@popperjs/core'
import React, {useState} from 'react'
import React, {useCallback, useState} from 'react'
import {usePopper} from 'react-popper'
import styles from 'part:@sanity/components/selects/searchable-style'
import FaAngleDown from 'part:@sanity/base/angle-down-icon'
Expand All @@ -12,11 +12,8 @@ import Escapable from '../utilities/Escapable'
import Stacked from '../utilities/Stacked'
import SelectMenu from './SelectMenu'

// interface Item {}

type Item = unknown

// @todo
type Item = unknown
type Value = any

interface StatelessSearchableSelectProps {
Expand Down Expand Up @@ -74,9 +71,12 @@ const StatelessSearchableSelect = React.forwardRef(
onHighlightIndexChange,
openItemElement,
readOnly,
renderItem: renderItemProp,
...rest
} = props

const itemsLen = items.length

const [referenceElement, setReferenceElement] = useState<HTMLElement | null>(null)
const [popperElement, setPopperElement] = useState<HTMLElement | null>(null)
const popper = usePopper(referenceElement, popperElement, {
Expand All @@ -94,74 +94,95 @@ const StatelessSearchableSelect = React.forwardRef(
]
})

const handleSelect = (item: Item) => {
if (onChange) onChange(item)
}
const handleSelect = useCallback(
(item: Item) => {
if (onChange) onChange(item)
},
[onChange]
)

const handleClose = useCallback(
(event?: Event) => {
if (onClose) onClose(event)
},
[onClose]
)

const handleArrowClick = (event?: React.MouseEvent<HTMLDivElement>) => {
const handleArrowClick = useCallback(() => {
if (isOpen) {
handleClose()
} else if (onOpen) onOpen()
}
}, [handleClose, isOpen, onOpen])

const handleArrowKeyPress = (event: React.KeyboardEvent<HTMLDivElement>) => {
if (event.key === 'Enter') {
handleArrowClick()
}
}
const handleArrowKeyPress = useCallback(
(event: React.KeyboardEvent<HTMLDivElement>) => {
if (event.key === 'Enter') {
handleArrowClick()
}
},
[handleArrowClick]
)

const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
if (onInputChange) onInputChange(event.target.value)
}
const handleInputChange = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
if (onInputChange) onInputChange(event.target.value)
},
[onInputChange]
)

// eslint-disable-next-line complexity
const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
if (event.key === 'ArrowDown' && !isOpen) {
if (onOpen) onOpen()
}
const handleKeyDown = useCallback(
// eslint-disable-next-line complexity
(event: React.KeyboardEvent<HTMLInputElement>) => {
if (event.key === 'ArrowDown' && !isOpen) {
if (onOpen) onOpen()
}

if (items.length === 0) {
return
}
if (itemsLen === 0) {
return
}

const lastIndex = items.length - 1
const lastIndex = itemsLen - 1

if (event.key === 'ArrowUp') {
event.preventDefault()
if (event.key === 'ArrowUp') {
event.preventDefault()

const nextIndex = highlightIndex - 1
const nextIndex = highlightIndex - 1

if (onHighlightIndexChange) {
onHighlightIndexChange(nextIndex < 0 ? lastIndex : nextIndex)
if (onHighlightIndexChange) {
onHighlightIndexChange(nextIndex < 0 ? lastIndex : nextIndex)
}
}
}

if (event.key === 'ArrowDown') {
event.preventDefault()
if (event.key === 'ArrowDown') {
event.preventDefault()

if (!isOpen && onOpen) onOpen()
if (!isOpen && onOpen) onOpen()

const nextIndex = highlightIndex + 1
const nextIndex = highlightIndex + 1

if (onHighlightIndexChange) {
onHighlightIndexChange(nextIndex > lastIndex ? 0 : nextIndex)
if (onHighlightIndexChange) {
onHighlightIndexChange(nextIndex > lastIndex ? 0 : nextIndex)
}
}
}
}

const handleKeyUp = (event: React.KeyboardEvent<HTMLInputElement>) => {
if (event.key === 'Enter' && highlightIndex > -1 && items[highlightIndex]) {
if (onChange) onChange(items[highlightIndex])
}
}
},
[highlightIndex, isOpen, itemsLen, onHighlightIndexChange, onOpen]
)

const handleClose = (event?: Event) => {
if (onClose) onClose(event)
}
const handleKeyUp = useCallback(
(event: React.KeyboardEvent<HTMLInputElement>) => {
if (event.key === 'Enter' && highlightIndex > -1 && items[highlightIndex]) {
if (onChange) onChange(items[highlightIndex])
}
},
[highlightIndex, items, onChange]
)

const renderItem = (item: Item) => {
return <div className={styles.item}>{props.renderItem(item)}</div>
}
const renderItem = useCallback(
(item: Item) => {
return <div className={styles.item}>{renderItemProp(item)}</div>
},
[renderItemProp]
)

return (
<>
Expand Down Expand Up @@ -228,20 +249,20 @@ const StatelessSearchableSelect = React.forwardRef(
>
<div
className={
items.length === 0 ? styles.listContainerNoResult : styles.listContainer
itemsLen === 0 ? styles.listContainerNoResult : styles.listContainer
}
>
<Escapable onEscape={handleClose} />
<div
className={
items.length === 0 && !isLoading
itemsLen === 0 && !isLoading
? styles.noResultText
: styles.noResultTextHidden
}
>
No results
</div>
{items.length > 0 && (
{itemsLen > 0 && (
<SelectMenu
items={items}
value={value}
Expand Down

0 comments on commit b46d603

Please sign in to comment.