1
0
mirror of https://github.com/oceanprotocol/market.git synced 2024-06-16 09:23:24 +02:00
market/src/components/@shared/FormInput/TagsAutoComplete.tsx
Luca Milanese 52eaee0ad5
Feat: autocomplete tags functionality (#1471)
* feat: add autocomplete tag component

* feat: pass tags aggregated list to autocomplete component

* feat: add initial styling to autocomplete tag component

* fix: autocomplete style types

* feat: move styling elements to module.css file

* feat: update placeholder text for tag input field

* feat: add default value to tags if present

* feat: add edit tags functionality

* fix: default tag value

* fix: style for automplete menu's keyboard navigation

* fix: tags aggregation query size

* feat: return sorted tags aggregated list suggestion in publish

* fix: set tags value touched state in edit mode

* add package back

* enhancement: autocomplete tag component config (#1679)

* fix publishing when connecting wallet on publish form

* fix reset pricing on tx execution

* removed changing steps

* cleanup

* Fix headers (#1663)

* test

* test

* test

* test

* test

* test

* test

* remove link

* enhancement: tag autocomplete settings

* feat: add cursor type text

* feat: tweak filter and sort for matched tags

* fix: tags input font color

* fix: tag autocomplete component input color

Co-authored-by: EnzoVezzaro <enzo-vezzaro@live.it>
Co-authored-by: mihaisc <mihai.scarlat@smartcontrol.ro>
Co-authored-by: Ana <84312885+AnaLoznianu@users.noreply.github.com>

* fix lock

* test

* fix

* fix

* minor fixes

* fix cursor on remove item (x)

* style updates

* UX tweaks

* start suggestions upon first key stroke
* remove redundant help tooltip
* change placeholder copy
* remove input clear action

* edit updates

Co-authored-by: mihaisc <mihai.scarlat@smartcontrol.ro>
Co-authored-by: EnzoVezzaro <enzo-vezzaro@live.it>
Co-authored-by: Ana <84312885+AnaLoznianu@users.noreply.github.com>
Co-authored-by: Matthias Kretschmann <m@kretschmann.io>
2022-10-05 15:40:00 +01:00

93 lines
2.7 KiB
TypeScript

import React, { ReactElement, useEffect, useState } from 'react'
import CreatableSelect from 'react-select/creatable'
import { OnChangeValue } from 'react-select'
import { useField } from 'formik'
import { InputProps } from '.'
import { getTagsList } from '@utils/aquarius'
import { chainIds } from 'app.config'
import { useCancelToken } from '@hooks/useCancelToken'
import styles from './TagsAutoComplete.module.css'
import { matchSorter } from 'match-sorter'
interface AutoCompleteOption {
readonly value: string
readonly label: string
}
export default function TagsAutoComplete({
...props
}: InputProps): ReactElement {
const { name, placeholder } = props
const [tagsList, setTagsList] = useState<AutoCompleteOption[]>()
const [matchedTagsList, setMatchedTagsList] = useState<AutoCompleteOption[]>(
[]
)
const [field, meta, helpers] = useField(name)
const [input, setInput] = useState<string>()
const newCancelToken = useCancelToken()
const generateAutocompleteOptions = (
options: string[]
): AutoCompleteOption[] => {
return options?.map((tag) => ({
value: tag,
label: tag
}))
}
const defaultTags = !field.value
? undefined
: generateAutocompleteOptions(field.value)
useEffect(() => {
const generateTagsList = async () => {
const tags = await getTagsList(chainIds, newCancelToken())
const autocompleteOptions = generateAutocompleteOptions(tags)
setTagsList(autocompleteOptions)
}
generateTagsList()
}, [newCancelToken])
const handleChange = (userInput: OnChangeValue<AutoCompleteOption, true>) => {
const normalizedInput = userInput.map((input) => input.value)
helpers.setValue(normalizedInput)
helpers.setTouched(true)
}
const handleOptionsFilter = (
options: AutoCompleteOption[],
input: string
): void => {
setInput(input)
const matchedTagsList = matchSorter(options, input, { keys: ['value'] })
setMatchedTagsList(matchedTagsList)
}
return (
<CreatableSelect
components={{
DropdownIndicator: () => null,
IndicatorSeparator: () => null
}}
className={styles.select}
defaultValue={defaultTags}
hideSelectedOptions
isMulti
isClearable={false}
noOptionsMessage={() =>
'Start typing to get suggestions based on tags from all published assets.'
}
onChange={(value: AutoCompleteOption[]) => handleChange(value)}
onInputChange={(value) => handleOptionsFilter(tagsList, value)}
openMenuOnClick
options={!input || input?.length < 1 ? [] : matchedTagsList}
placeholder={placeholder}
theme={(theme) => ({
...theme,
colors: { ...theme.colors, primary25: 'var(--border-color)' }
})}
/>
)
}