* initial implementation of search modal * added hit and search suggestions * added support for multiple indices * updated sample env * added close when click outside dropdown * test for mobile * added mobile design * added shortcut * dark mode fixes * added search to docs * added plugins filter * added React import * moved filters to configurations * handled error on page load * change suggestion text * removed hits limit * handle select all * open link in current tab * change highlight colors * added support for shortcuts + auto focus * change header and footer * redesigned search ui
94 lines
2.3 KiB
TypeScript
94 lines
2.3 KiB
TypeScript
import { useCallback, useMemo } from "react"
|
|
|
|
export type OptionType = {
|
|
value: string
|
|
label: string
|
|
index?: string
|
|
isAllOption?: boolean
|
|
}
|
|
|
|
export type SelectOptions = {
|
|
value: string | string[]
|
|
multiple?: boolean
|
|
options: OptionType[]
|
|
setSelected?: (value: string | string[]) => void
|
|
addSelected?: (value: string) => void
|
|
removeSelected?: (value: string) => void
|
|
handleAddAll?: (isAllSelected: boolean) => void
|
|
}
|
|
|
|
const useSelect = ({
|
|
value,
|
|
options,
|
|
multiple = false,
|
|
setSelected,
|
|
addSelected,
|
|
removeSelected,
|
|
handleAddAll,
|
|
}: SelectOptions) => {
|
|
const isValueSelected = useCallback(
|
|
(val: string) => {
|
|
return (
|
|
(typeof value === "string" && val === value) ||
|
|
(Array.isArray(value) && value.includes(val))
|
|
)
|
|
},
|
|
[value]
|
|
)
|
|
|
|
// checks if there are multiple selected values
|
|
const hasSelectedValues = useMemo(() => {
|
|
return multiple && Array.isArray(value) && value.length > 0
|
|
}, [value, multiple])
|
|
|
|
// checks if there are any selected values,
|
|
// whether multiple or one
|
|
const hasSelectedValue = useMemo(() => {
|
|
return hasSelectedValues || (typeof value === "string" && value.length)
|
|
}, [hasSelectedValues, value])
|
|
|
|
const selectedValues: OptionType[] = useMemo(() => {
|
|
if (typeof value === "string") {
|
|
const selectedValue = options.find((option) => option.value === value)
|
|
return selectedValue ? [selectedValue] : []
|
|
} else if (Array.isArray(value)) {
|
|
return options.filter((option) => value.includes(option.value))
|
|
}
|
|
return []
|
|
}, [options, value])
|
|
|
|
const isAllSelected = useMemo(() => {
|
|
return Array.isArray(value) && value.length === options.length
|
|
}, [options, value])
|
|
|
|
const handleChange = (selectedValue: string, wasSelected: boolean) => {
|
|
if (multiple) {
|
|
wasSelected
|
|
? removeSelected?.(selectedValue)
|
|
: addSelected?.(selectedValue)
|
|
} else {
|
|
setSelected?.(selectedValue)
|
|
}
|
|
}
|
|
|
|
const handleSelectAll = () => {
|
|
if (handleAddAll) {
|
|
handleAddAll(isAllSelected)
|
|
} else {
|
|
setSelected?.(options.map((option) => option.value))
|
|
}
|
|
}
|
|
|
|
return {
|
|
isValueSelected,
|
|
hasSelectedValue,
|
|
hasSelectedValues,
|
|
selectedValues,
|
|
isAllSelected,
|
|
handleChange,
|
|
handleSelectAll,
|
|
}
|
|
}
|
|
|
|
export default useSelect
|